1. ホーム
  2. c

[解決済み] C言語で標準入力をEOFまで文字列変数に読み込むには?

2022-02-05 13:40:25

質問

を読み込もうとすると、quot;Bus Error"が発生します。 stdinchar* 変数を使用します。 を越えてくるものを全部読みたいだけなんです stdin で、それをまず変数に入れ、その後、その変数で作業を続ける。

私のコードは以下の通りです。

char* content;
char* c;
while( scanf( "%c", c)) {
 strcat( content, c);
}

fprintf( stdout, "Size: %d", strlen( content));

を呼び出すと、なぜかいつも "Bus error" が返されます。 cat test.txt | myapp ここで myapp は、上記のコンパイルされたコードです。

私の質問は、どのように stdin EOFまで変数に入れますか?コードにあるように、私はただ標準入力から来る入力のサイズを表示したいだけです。 test.txt .

を使うだけでいいと思いました。 scanf を読むためのバッファリングがあれば十分でしょう。 stdin ?

解決方法は?

まず、初期化されていないポインターを渡している、ということです。 scanfstrcat は、自分が持っていないメモリを書き込むことになります。 2つ目は strcat はヌル文字で終端する2つの文字列を期待しますが、cは単なる文字です。 これもまた、あなたが所有していないメモリを読み込む原因となる。 実際の処理をしているわけではないので、scanfは必要ない。 最後に、1文字ずつ読むと無駄に遅くなります。 最終的な文字列にはサイズ変更可能なバッファを使用し、fgets呼び出しには固定バッファを使用する解決策の始まりです。

#define BUF_SIZE 1024
char buffer[BUF_SIZE];
size_t contentSize = 1; // includes NULL
/* Preallocate space.  We could just allocate one char here, 
but that wouldn't be efficient. */
char *content = malloc(sizeof(char) * BUF_SIZE);
if(content == NULL)
{
    perror("Failed to allocate content");
    exit(1);
}
content[0] = '\0'; // make null-terminated
while(fgets(buffer, BUF_SIZE, stdin))
{
    char *old = content;
    contentSize += strlen(buffer);
    content = realloc(content, contentSize);
    if(content == NULL)
    {
        perror("Failed to reallocate content");
        free(old);
        exit(2);
    }
    strcat(content, buffer);
}

if(ferror(stdin))
{
    free(content);
    perror("Error reading from stdin.");
    exit(3);
}

EDIT: Wolferが言及したように、入力にNULLがあると、fgetsを使用する際に文字列が早期に終了してしまいます。 ゲットライン は、メモリ割り当てを処理し、NUL入力の問題がないため、利用可能であれば、より良い選択です。