【问题标题】:My structure array prints garbage after returning from a file从文件返回后,我的结构数组打印垃圾
【发布时间】:2021-01-14 14:09:44
【问题描述】:

我对 C 语言非常陌生,我正在尝试从包含姓名和电话号码的文件中逐行读取。然后我需要动态分配一个结构数组,并用文件中的名称和编号填充该数组。这很有效,当我在执行此操作的函数中打印出来时效果很好,但是当我返回结构并尝试在main 中打印时,它会在框中打印问号。

这是文件的样子:

亚伦 7774013 乔恩 7774014 托马斯 7774015 马特 7774016

这些是相关的代码部分(如果您需要查看更多信息,请告诉我):

struct _data {
    char *name;
    long number;
};

struct _data *LOAD(FILE *stream, int size) {
    char str[50];
    char *token;
    int i;
    struct _data *BlackBox = calloc(size, sizeof(struct _data));
    stream = fopen("hw4.data.txt", "r");
    for (i = 0; i < size; i++) {
        if (fgets(str, 50, stream) != NULL) {
            token = strtok(str, " ");
            BlackBox[i].name = token;
            printf("%s\n", BlackBox[i].name); //prints just fine
            puts(token);
            while (token != NULL) {
                token = strtok(NULL, " ");
                BlackBox[i].number = atoi(token);
                break;
            }   
        }
    }
    fclose(stream);
    return BlackBox;
}

这是在main 函数中

FILE *stream;

int size = scan(&stream);
struct _data *BlackBox = LOAD(stream, size);
for (i = 0; i < size; i++) {
    printf("%s\n", BlackBox[i].name);  //prints out garbage
} 

【问题讨论】:

  • token = strtok(str, " "); BlackBox[i].name = token; 不正确,因为str 是一个局部变量。一旦函数退出,它就会失效。分配动态内存,然后将字符串复制到缓冲区中(或使用strdup 作为快捷方式)。
  • 此外,您将相同的str 分配给多个BlackBox 条目。不可能每个条目都有不同的字符串值 - 作为测试,在 for 循环之后的循环中执行 printf,你会看到。

标签: arrays c file structure


【解决方案1】:

char str[50]; 是一个局部变量,在您离开函数时,程序分配的内存将丢失。 你不能再访问它了。

Fix : 不要将固定内存分配给 str 而是动态的。

我建议从 main 创建 str 并将她的地址传递给 LOAD,然后您将能够使用 LOAD 修改地址的内容。

【讨论】:

    【解决方案2】:

    您在使用strtok 的结果时犯了错误。您最好将结果复制到自己的内存中,而不是仅获取 char * 指针,例如

    // This is only an example, remember to allocate large enough memory for
    // `BlackBox[i].name` to save the content got from `token`
    #define LEN 64
    
    struct _data{
        char name[LEN];
        long number;
    };
    struct _data *BlackBox = calloc(size, sizeof(struct _data));
    
    //...
    token = strtok(str, " ");
    
    // Instead of
    //
    // BlackBox[i].name = token;
    //
    // You should copy
    strncpy(BlackBox[i].name, token, LEN-1); 
    

    您可以参考strtok。

    【讨论】:

    • 而你没有分配任何内存,而strncpy对源的strlen有双重错误
    猜你喜欢
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 2021-01-15
    • 2012-11-05
    • 2015-06-28
    相关资源
    最近更新 更多