c - 将文件读入字符串数组 C

标签 c arrays file-io c-strings

我无法将文件读入 C 中的字符串数组。这是我的代码:

  char mylittleBuffer[BUFFER_SIZE];     //BUFFER_SIZE is 4096
  char *a;
  char **c;

  fprintf(stderr, "LOL\n");
  for(int i = 0; (a = fgets(mylittleBuffer, sizeof(mylittleBuffer), myInput)) != NULL; i++)
    {
      fprintf(stderr, "a: %s\n", a);
      c[i] = malloc(sizeof(a));
      if (c[i] == NULL)
        printf("c[i] is NULL");
      c[i] = strdup(a);
      //      fprintf(stderr, "mylittleBuffer: %s\n", mylittleBuffer);                                                                                                                                                   
      fprintf(stderr, "c[i] %s\n", c[i]);
    }

似乎只读取了文件的一行,因为程序将打印出 a 一次。其他线路怎么了?我没有收到任何错误消息...

  1. 这里有什么问题?
  2. 我该如何解决这个问题?

最佳答案

你还没有初始化c指向任何东西(你需要为它分配空间),所以当你使用c[i]时,你正在使用未定义的内存位置,调用未定义的行为。它没有崩溃是一个奇迹。您将需要为字符指针数组分配空间。

enum { INITIAL_SIZE = 2 };            // Set to a larger number when not debugging
char mylittleBuffer[BUFFER_SIZE];     //BUFFER_SIZE is 4096
char *a;
size_t c_size = INITIAL_SIZE;
char **c = malloc(c_size * sizeof(*c));

if (c == NULL)
{
    fprintf(stderr, "out of memory (for c)\n");
    return;
}

fprintf(stderr, "LOL\n");
for (int i = 0; (a = fgets(mylittleBuffer, sizeof(mylittleBuffer), myInput)) != NULL; i++)
{
    fprintf(stderr, "a: %s\n", a);
    if (i >= c_size)
    {
         // Reallocate c to get more space
         size_t new_size = c_size * 2;
         void *new_space = realloc(c, new_size * sizeof(*c));
         if (new_space == 0)
         {
             // Release the already allocated c[i]
             // Release c
             fprintf(stderr, "Out of memory (for more c)\n");
             return;
         }
         c_size = new_size;
         c = new_space;
    }
    // c[i] = malloc(sizeof(a));  // Leak - you use strdup() too
    c[i] = strdup(a);
    if (c[i] == NULL)
    {
        fprintf(stderr, "c[i] is NULL\n");
        // Release the already allocated c[i] strings
        // Release c
        return;
    }
    //      fprintf(stderr, "mylittleBuffer: %s\n", mylittleBuffer);
    fprintf(stderr, "c[%d] <<%s>>\n", i, c[i]);  // <<>> show where the string ends
}

我主要保留了您的代码。如果它是我的,a 将不存在,mylittleBuffer 将只是 buffer,这就是我在循环体中使用的内容a 的位置。我可能会为 c 使用更长的名称,尽管我通常使用比其他人更短的名称。

请注意使用 realloc() 的代码如何避免在调用失败时丢失指向先前分配的内存的指针。如果它直接分配给 c,您将失去对先前内存分配的唯一引用 — 可能是重大泄漏。

鉴于清理代码需要两次,我将编写一个函数来执行此操作:

static void release_memory(size_t num, char **strings)
{
    for (size_t i = 0; i < num; i++)
        free(strings[i]);
    free(strings);
}

它会被称为:

release_memory(i, c);

关于c - 将文件读入字符串数组 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21651066/

相关文章:

arrays - SSRS Reporting Services - 字符串中的粗体字

java - 计算多维数组的哈希码时使用 Arrays.deepHashCode() 的技术原因

java - 在处理项目文件夹内容时如何使用文件路径?

php - 仅当文件路径具有特定扩展名时才显示数组行

java - 我应该序列化 keyPressed 吗?

c++ - 使用 C 和/或 C++ 在内存中创建和管理字节缓冲区,该缓冲区可以根据需要自动调整大小

c - 是否需要保留填充位?

C程序显示顺序

c - 为什么这些构造使用增量前和增量后未定义的行为?

c - INT_MIN 及其正等价物大小相同