[英]Print a string reversed in C
我正在编写一个程序,它将一些文件作为参数并打印所有相反的行。 问题是我得到了意想不到的结果:
如果我将它应用于包含以下行的文件
one
two
three
four
我得到了预期的结果,但如果文件包含
september
november
december
它回来了
rebmetpes
rebmevons
rebmeceds
而且我不明白为什么它最后增加了一个“s”
这是我的代码
#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
字符终止你的字符串。 在反转字符串\\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'
我想我知道这个问题,这有点奇怪。
C中的字符串为零终止。 这意味着字符串“嗨!” 在记忆中实际上表示为'H','i','!','\\0'
。 strlen
等的方式然后知道字符串的长度是通过计算字符数,从第一个字符开始,在零终止符之前。 类似地,当打印字符串时, fprintf
将打印所有字符,直到它到达零终止符。
问题是,你的reverse
函数永远不会在最后设置零终结符,因为你需要逐个字符地将字符复制到缓冲区中。 这意味着它会在你分配的res
缓冲区的末尾运行,并运行到未定义的内存中,当你点击它时恰好是零( malloc
没有对你分配的缓冲区内容做出承诺,只是它足够大)。 您应该在Windows上获得不同的行为,因为我相信在调试模式下, malloc
会将所有缓冲区初始化为0xcccccccc。
所以,正在发生的事情是你把9月份复制成res
。 这就像你看到的那样,因为它恰好在最后有一个零。
然后你释放res
,然后再次malloc
它。 再次,偶然(并且由于malloc
的某些智能),您将获得相同的缓冲区,其中已包含“rebmetpes”。 然后你将“11月”放入,反转,这稍微缩短,因此你的缓冲区现在包含“rebmevons”。
那么,修复? 分配另一个字符,这将保留你的零终止符( char *res = malloc( longitud * sizeof(char) + 1);
)。 反转字符串后,在字符串末尾设置零终止符( res[longitud] = '\\0';
)。
那里有两个错误,第一个是你需要一个更多的char分配(字符串的所有字符+终结符的1个字符)
char *res = malloc( (longitud+1) * sizeof(char) );
第二个是你必须终止字符串:
res[longitud]='\0';
您可以在进入循环之前终止字符串,因为您已知道目标字符串的大小。
请注意,使用calloc
而不是malloc
您将不需要终止字符串,因为内存得到了零初始化
谢谢,它解决了我的问题。 我在字符串中读到了一些关于“\\ 0”的内容但是不是很清楚,现在在阅读完所有答案之后(一切都很好)。 谢谢大家的帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.