[英]dynamic buffer size for reading input
我正在嘗試創建一個程序,該程序將從stdin逐行讀取,在該行中搜索給定單詞的開頭和結尾,並輸出所有匹配的單詞。 這是代碼:
int main()
{
char buffer[100];
char **words = NULL;
int word_count = 0;
while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
int length = strlen(buffer);
if (buffer[length - 1] == '\n') {
word_count = count_words(buffer, FIRSTCHAR);
if (word_count > 0) {
words = get_words(buffer, FIRSTCHAR, LASTCHAR);
for (int i = 0; i < word_count; ++i) {
printf("%s\n", words[i]);
free(words[i]);
}
free(words);
}
}
}
return 0;
}
我可以使用基本功能,但是我依賴具有固定緩沖區大小的fgets()。 我想要動態分配一個內存緩沖區,其大小基於每行的長度。
我只能看到一種解決它的方法,該方法是使用fgetc遍歷輸入並遞增一個計數器直到行尾,然后使用該計數器代替sizeof(buffer) ,但是我不知道該怎么做。 fgetc讀取正確的相關行。
有解決這個問題的聰明方法嗎?
但我依賴具有固定緩沖區大小的
fgets()
。 我想動態分配一個內存緩沖區,其大小基於每行的長度
我確實為另一個SO答案寫了一個fgets
版本,該答案讀取了整行並返回了包含整行內容的malloc
分配指針。 這是代碼:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *fgets_long(FILE *fp)
{
size_t size = 0, currlen = 0;
char line[1024];
char *ret = NULL, *tmp;
while(fgets(line, sizeof line, fp))
{
int wholeline = 0;
size_t len = strlen(line);
if(line[len - 1] == '\n')
{
line[len-- - 1] = 0;
wholeline = 1;
}
if(currlen + len >= size)
{
// we need more space in the buffer
size += (sizeof line) - (size ? 1 : 0);
tmp = realloc(ret, size);
if(tmp == NULL)
break; // return all we've got so far
ret = tmp;
}
memcpy(ret + currlen, line, len + 1);
currlen += len;
if(wholeline)
break;
}
if(ret)
{
tmp = realloc(ret, currlen + 1);
if(tmp)
ret = tmp;
}
return ret;
}
訣竅是檢查是否已讀取換行符。 如果已讀取,則可以返回緩沖區,否則它將使用sizeof line
重新分配緩沖區更多字節,並將其追加到緩沖區。 您可以根據需要使用此功能。
另一種選擇是,如果您使用的是POSIX系統和/或正在使用GNU GCC進行編譯,則也可以使用getline
。
void foo(FILE *fp)
{
char *line = NULL;
size_t len = 0;
if(getline(&line, &len, fp) < 0)
{
free(line); // man page says even on failure you should free
fprintf(stderr, "could not read whole line\n");
return;
}
printf("The whole line is: '%s'\n", line);
free(line);
return;
}
函數: getline()
您的需求。 語法:
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
該函數在stdio.h
頭文件中公開,通常需要類似以下內容: #define _POSIX_C_SOURCE 200809L
或#define _GNU_SOURCE
作為調用getline()
的文件的第一行
強烈建議您閱讀/理解`getline()的MAN頁面,以獲取所有骯臟的細節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.