繁体   English   中英

打印C中反转的字符串

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM