[英]C: how to read in a variable amount of info from files and store it in array
我不習慣用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));
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));
數組總是固定大小為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
有效,但不保證是這種情況。
在您閱讀換行符之前,您似乎正在嘗試閱讀。
最簡單的方法是通過getline 。
char *buffer = NULL;
int buffer_len;
int ret = getline(&buffer, &buffer_len, file);
...這將從文件file
讀取一行文本(除非ret
為-1
,其中存在錯誤或者您在文件的末尾)。
字符串數據在數組條目中的數組通常是非最佳選擇。 如果完整的數據集合適合內存並且條目數有合理的上限,則指針數組是一種選擇。
但首先,避免使用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的內存分配和分頁很好地配合使用。 使用一組函數從這個字符串數組中有效地創建一個對象將有助於您的開發。 您可以選擇一個簡單的策略,如上所述,並在以后優化實施。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.