簡體   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