【问题标题】:Why is my program outputting garbage characters? (Language: C)为什么我的程序输出乱码? (语言:C)
【发布时间】:2021-12-24 07:32:50
【问题描述】:

我有以下问题:

对于一个作业,我应该逐行读取一个 txt 文件,将每一行作为链表中的元素,然后以正确的顺序打印出来。

如果我正确理解调试器,我已经实现了这一点,但我的输出看起来一团糟。我怀疑 nulltermination 是错误的,但这里似乎不是这种情况(见下文)。 Picture of the output

为了可读性,我没有写出整个代码,只是我认为是程序的重要部分。

#include <stdlib.h>
#include <stdio.h>

typedef struct node{
    struct node *p;
    char* string;
}node;

char *readline(FILE *stream)
//returns reference to string, returns NULL if EOF is reached before any char was read.
//If a line is EOF terminated it will return the string to the point where EOF was reached.
{
    char *string = malloc(sizeof(char));
    char c;
    int len = 0;
    if((c = getc(stream)) == EOF) return NULL;
    do{
        *(string + len) = c;
        len++;
        realloc(string, (sizeof(char)*(len)+1));
        if(c == '\n') break;
    }while((c = getc(stream)) != EOF);
    string[len] = '\0'; //make it nullterminated
    return string;
}

node *new_node(FILE* stream)
// creates a new node from a line read by the readline() function.
{
    node *new = malloc(sizeof(node));
    new->string = readline(stream);
    new->p = NULL;
    return new;
}

void tail(node *newnode, node *head)
{
    node *tmp = head;
    while(tmp->p != NULL)
    {
        tmp = tmp->p;
    }
    tmp->p = newnode;
}

int main()
{
    FILE *moby = fopen("testtxt.txt", "r");
    if(moby == NULL) perror("FILE ERROR");
    node *head = new_node(moby);
    node *tmp;

    //constructing the list
    while((tmp = new_node(moby))->string != NULL)
    {
        tail(tmp, head);
    }

    //printing the list
    while(1){
        printf("%s", head->string);
        if(head->p == NULL) break; //end of linked list is reached
        head = head->p;
    }

    fclose(moby);
    return 0;
}

尤其是以下部分似乎与我构建“字符串”的方式存在问题:

while(1){
        printf("%s", head->string);
        if(head->p == NULL) break; //end of linked list is reached
        head = head->p;
    }

我的理解是,为了让 printf 与 %s 修饰符一起工作,字符串必须以空字符结尾。我想我通过string[len] = '\0'; 实现了这一点,从调试器向我展示的内容来看,我实现它的方式是有效的。 Screenshot of the debug. 我还让调试器将它解释为一个数组,这样我就可以看到 '\0' 字符是否在我期望的位置,就是这种情况。 Screenshot of the debug.

现在我有点不知所措,因为我找不到这个问题的其他示例,而且调试器似乎告诉我我正在生成正确的数据。

我希望我只是漏掉了一个别人能够发现的小细节。

TIA

(我用的是eclipse,win 10控制台和eclipse控制台输出一致)

【问题讨论】:

  • 也许你把堆栈弄坏了?
  • @Shark 我也这么认为,但 4386427 是对的。它现在正在工作。我只是在重新分配内存后没有保存。所以我想我很幸运 realloc 没有更改某些数字的第一个地址。

标签: c string printf


【解决方案1】:

可能还有其他问题,但是你使用realloc是错误的。

这里

realloc(string, (sizeof(char)*(len)+1));

您需要保存返回值,因为这是分配的内存所在。

喜欢

char* temp = realloc(string, (sizeof(char)*(len)+1));
if (temp == NULL)
{
    // add error handling
}
string = temp;

与所描述的问题无关:

当您一直想将新元素添加到列表末尾时,最好使用指向最后一个元素的tail 指针。这将使插入速度更快,因为您不需要 while(tmp-&gt;p != NULL) 循环。

【讨论】:

  • 感谢您的帮助。我真的很幸运 realloc 有时不必更改第一个元素的指针吗?根据我的理解,realloc 可以,但不必改变内存中块的位置,只要内存块变得太大,它就会改变位置,然后改变指向第一个地址的指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
相关资源
最近更新 更多