C:如何从文件中读取可变数量的信息并将其存储在数组中

时间:2012-10-23 02:07:41

标签: c

我不习惯用c编程,所以我想知道如何有一个数组,然后在文件中读取可变数量的变量,以及这些文件在数组中。

//how do I declare an array whose sizes varies
do {
     char buffer[1000];
     fscanf(file, %[^\n]\n", buffer);
     //how do i add buffer to array
}while(!feof(file)); 

4 个答案:

答案 0 :(得分:2)

int nlines = 0
char **lines = NULL; /* Array of resulting lines */
int curline = 0;
char buffer[BUFSIZ]; /* Just alloocate this once, not each time through the loop */
do {
     if (fgets(buffer, sizeof buffer, file)) { /* fgets() is the easy way to read a line */
       if (curline >= nlines) { /* Have we filled up the result array? */
         nlines += 1000; /* Increase size by 1,000 */
         lines = realloc(lines, nlines*sizeof(*lines); /* And grow the array */
       }
       lines[curline] = strdup(buffer); /* Make a copy of the input line and add it to the array */
       curline++;
     }
}while(!feof(file)); 

答案 1 :(得分:1)

数组在C中始终是固定大小的。您无法更改其大小。您可以做的是事先估计您需要多少空间并动态分配该空间(使用malloc())。如果您的空间不足,则需要重新分配。请参阅realloc()的文档。基本上,你这样做:

buffer = realloc(size);

新尺寸可以比之前更大或更小(意味着您可以“增长”或“缩小”数组。)因此,如果您首先想要空间为5000个字符,那么您可以:

char* buffer = malloc(5000);

如果以后你的空间不足并想要额外的2000个字符(所以新的大小将是7000),你会这样做:

buffer = realloc(7000);

保留已存在的buffer内容。请注意,realloc()可能无法真正增加内存块,因此它可能首先分配一个全新的块,然后将旧内存的内容复制到新块,然后释放旧内存。这意味着如果您将buffer指针的副本存储在其他位置,它将指向不再存在的旧内存块。例如:

char* ptr = buffer;
buffer = realloc(7000);

此时,ptr仅在ptr == buffer有效时才有效, 保证不是这样。

答案 2 :(得分:0)

在您阅读换行符之前,您似乎正在尝试阅读。

最简单的方法是通过getline

char *buffer = NULL;
int buffer_len;
int ret = getline(&buffer, &buffer_len, file);

...这将从文件file中读取一行文字(除非ret-1,其中有错误或您在文件的末尾)。

答案 3 :(得分:0)

字符串数据在数组条目中的数组通常是非最佳选择。如果完整的数据集合适合内存并且条目数有合理的上限,则指针数组是一种选择。

但首先,避免使用scanf%s和%[]格式而没有明确的长度。使用1000的示例缓冲区大小,您可以读取的最大字符串长度为999,因此:

/* Some needed data */
int n;
struct ptrarray_t
{
    char **strings;
    int  nalloc; /* number of string pointers allocated */
    int  nused;  /* number of string pointers used */
} pa_hdr; /* presume this was initialized previously */
...
n = fscanf(file, "%999[\n]", buffer);
if (n!=1 || getc(file)!='\n')
{
    there's a problem
}
/* Now add a string to the array */
if (pa_hdr.nused < pa_hdr.nalloc)
{
    int len = strlen(buffer);
    char *cp = malloc(len+1);
    strcpy(cp, buffer);
    pa_hdr.strings[pa_hdr.nused++] = cp;
}

以下对任何字符串的引用只是pa_hdr.strings [i],一个不错的设计将使用函数调用或宏来管理标题,而标题又将在头文件中而不是内联。当你完成数组后,你需要一个删除函数来释放所有那些malloc()ed指针。

如果存在大量小字符串,则malloc()的开销时间和空间都很昂贵。您可以管理较大块中的字符串池,这些块将与主机OS的内存分配和分页很好地配合使用。使用一组函数从这个字符串数组中有效地创建一个对象将有助于您的开发。您可以选择一个简单的策略,如上所述,并在以后优化实施。