【问题标题】:changing size of array改变数组的大小
【发布时间】:2013-09-20 15:49:21
【问题描述】:

我有以下代码:

typedef struct my_data {
 char* name;
}my_data;

my_data data[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};


void loaddata()
{
    FILE * in;
    if((in = fopen("data.txt","rt")) != NULL) {
        memset(data, 0, sizeof(data));
        int i = 0;
        while(!feof(in))
        {
            fscanf(in,"%s", &data[i].name);
            i++;
        };
        fclose(in);
    }
}

要读取内容并处理它们,我使用这个:

for (i=0; i<sizeof(data)/sizeof(data[0]); i++)

但是如果文件中的行数小于定义数组的数量,我会得到很多空记录,所以我将其修改为:

for (i=0; (i<sizeof(data)/sizeof(data[0])) && strlen(data[i].name)>0; i++)

这工作正常,但如果文件中的行数大于定义的数组大小,我肯定会出错。

知道如何使这段代码安全吗?动态改变数组?

编辑: 这种方式适用于尺寸 300

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

 typedef struct my_data {
    char name[100];
}my_data;

struct my_data data[300];

my_data data_arr[]={
    { .name = "Peter" },
    { .name = "James" },
    { .name = "John" },
    { .name = "Mike" }
};

void process_data()
{
    char name[100];
    int i;
    for (i=0; (i<sizeof(data)/sizeof(data[0])) && strlen(data[i].name)>0; i++) {
        sprintf(name, "%s", data[i].name);
        printf("%s\n", name);
    }
}

void load_data()
{
    int i = 0;
    FILE * in;
    if((in = fopen("data.txt","rt")) != NULL) {
        while(!feof(in))
        {
            fscanf(in,"%s", &data[i].name);
            i++;
        };
        fclose(in);
    }
    else
    {
        for (i=0; (i<sizeof(data_arr)/sizeof(data_arr[0])) && strlen(data_arr[i].name)>0; i++) {
            sprintf(data[i].name, "%s", data_arr[i].name);
        }
    }
    return;
}

int main()
{
    load_data();
    process_data();
    return 0;
}

【问题讨论】:

  • 不要使用feof 来终止您的输入循环。改为检查fscanf 返回的结果。仅在循环结束后使用feof,并且仅当您想确定fscanf 是否由于文件结束条件或错误条件而失败时。

标签: c arrays struct structure


【解决方案1】:

数组在 C 中不会动态增长。因此您有几种方法:

  1. 获取指向内存块的指针(使用malloc)并在需要更多空间用于数组时使用realloc - 并索引到您的指针
  2. 使用malloc 为您要添加到列表中的每个新项目创建一个链接列表

不要忘记使用malloc 对您调用malloc 的每个块调用free 时。

【讨论】:

  • 我阅读了这个并找到了一些示例,但我想我无法正确实现它,因为我每次都遇到分段错误
  • @SamReina 内存管理很难。这就是为什么存在像valgrind 这样的优秀工具来查找代码中的内存管理问题的原因。您也可以考虑使用 C++ 中的容器 - 如果您不想处理低级指针和内存分配,它们可以动态增长(参见 Vector)。
  • 非常感谢!你用这个信息拯救了我的一天。我不需要使用 valgrind 或 gdb 来检查我已经知道是错误的东西。我可以很容易地做到这一点: while(!feof(in)) { temp = malloc(sizeof(my_data)); if(temp_1 != NULL) temp_1->next = temp; fscanf(in,"%s",temp->name);临时->下一个 = NULL; ... bla bla 但我还需要默认数组以防文件丢失,所以如果你能回答我的问题,我会感谢你,但不要给我像 valgrind 这样的解决方案来解决这个特定问题。
猜你喜欢
  • 2012-10-01
  • 2012-04-17
  • 2016-05-12
  • 2022-01-01
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
相关资源
最近更新 更多