我正在编写一个程序,它将一些文件作为参数并打印所有反转的行。问题是我得到了意想不到的结果:
如果我将其应用于包含以下行的文件
one
two
three
four
我得到了预期的结果,但是如果文件包含
september
november
december
返回
rebmetpes
rebmevons
rebmeceds
而且我不明白为什么它会添加一个""最后
这是我的代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void reverse(char *word);
int main(int argc, char *argv[], char*envp[]) {
/* No arguments */
if (argc == 1) {
return (0);
}
FILE *fp;
int i;
for (i = 1; i < argc; i++) {
fp = fopen(argv[i],"r"); // read mode
if( fp == NULL )
{
fprintf(stderr, "Error, no file");
}
else
{
char line [2048];
/*read line and reverse it. the function reverse it prints it*/
while ( fgets(line, sizeof line, fp) != NULL )
reverse(line);
}
fclose(fp);
}
return (0);
}
void reverse(char *word)
{
char *aux;
aux = word;
/* Store the length of the word passed as parameter */
int longitud;
longitud = (int) strlen(aux);
/* Allocate memory enough ??? */
char *res = malloc( longitud * sizeof(char) );
int i;
/in this loop i copy the string reversed into a new one
for (i = 0; i < longitud-1; i++)
{
res[i] = word[longitud - 2 - i];
}
fprintf(stdout, "%s\n", res);
free(res);
}
(注意:为清楚起见,已删除了一些代码,但应编译)
答案 0 :(得分:4)
您忘记使用\0
字符终止字符串。在反转中,字符串\0
成为反向字符串的第一个字符。首先为比你分配的字符多一个字符分配内存
char *res = malloc( longitud * sizeof(char) + 1);
试试这个
for (i = 0; i < longitud-1; i++)
{
res[i] = word[longitud - 2 - i];
}
res[i] = '\0'; // Terminating string with '\0'
答案 1 :(得分:1)
我想我知道这个问题,这有点奇怪。
C中的字符串为零终止。这意味着字符串&#34;嗨!&#34;在内存中实际表示为'H','i','!','\0'
。然后strlen
等方式知道字符串的长度是通过计算字符数,从第一个字符开始,在零终止符之前。同样,在打印字符串时,fprintf
将打印所有字符,直到它到达零终结符。
问题是,你的reverse
函数永远不会在最后设置零终结符,因为你需要逐个字符地将字符复制到缓冲区中。这意味着它在你分配的res
缓冲区的末尾运行,并进入未定义的内存,当你点击它时恰好为零(malloc
没有对你分配的缓冲区内容做出承诺,只是它足够大了)。您应该在Windows上获得不同的行为,因为我相信在调试模式下,malloc
会将所有缓冲区初始化为0xcccccccc。
所以,你正在发生的事情是将9月复制到res
。这就像你看到的那样有效,因为它恰好在最后有一个零。
然后,您再次释放res
,然后malloc
。再次,偶然(并且由于malloc
中的一些聪明)你得到了相同的缓冲区,它已经包含了&#34; rebmetpes&#34;。然后你把&#34; 11月&#34; in,reverse,稍短,因此你的缓冲区现在包含&#34; rebmevons&#34;。
那么,修复?分配另一个字符,这将保留您的零终结符(char *res = malloc( longitud * sizeof(char) + 1);
)。反转字符串后,在字符串末尾设置零终止符(res[longitud] = '\0';
)。
答案 2 :(得分:1)
有两个错误,第一个是你需要一个更多的char分配(字符串的所有字符+终结符的1个字符)
char *res = malloc( (longitud+1) * sizeof(char) );
第二个是你必须终止字符串:
res[longitud]='\0';
您可以在进入循环之前终止字符串,因为您已知道目标字符串的大小。
请注意,使用calloc
而不是malloc
,您将不需要终止字符串,因为内存已被零初始化
答案 3 :(得分:0)
谢谢,它解决了我的问题。我在字符串中读到了一些关于“\ 0”的内容但是不是很清楚,现在在阅读完所有答案之后(一切都很好)。谢谢大家的帮助。