2

これは、バグを見つけるための良い質問になる可能性があります。いいえ?少なくとも初心者には大丈夫です。

#define SIZE 4
int main(void){
  int chars_read = 1;
  char buffer[SIZE + 1] = {0};  
  setvbuf(stdin, (char *)NULL, _IOFBF, sizeof(buffer)-1);  
  while(chars_read){
    chars_read = fread(buffer, sizeof('1'), SIZE, stdin);
    printf("%d, %s\n", chars_read, buffer);
  }
  return 0;
}

Using the above code, I am trying to read from a file using redirection ./a.out < data. Contents of input file:

1line
2line
3line
4line

But I am not getting the expected output, rather some graphical characters are mixed in. What is wrong?


Hint: (Courtesy Alok)

  • sizeof('1') == sizeof(int)
  • sizeof("1") == sizeof(char)*2

So, use 1 instead :-)

Take a look at this post for buffered IO example using fread

4

3 に答える 3

9

のタイプはで'1'intなくCであるため、各のバイトをchar読み取っています。が1より大きい場合(最近のほとんどのコンピューターではそうです)、のストレージを超えて読み取っています。これは、CとC ++が異なる場所の1つです。Cでは、文字リテラルは型であり、C ++では、型です。SIZE*sizeof(int)freadsizeof(int)bufferintchar

したがって、定義上1であるchars_read = fread(buffer, 1, SIZE, stdin);ため、必要です。sizeof(char)

実際、私はあなたのループを次のように書きます:

while ((chars_read = fread(buffer, 1, sizeof buffer - 1)) > 0) {
    buffer[chars_read] = 0; /* In case chars_read != sizeof buffer - 1.
                               You may want to do other things in this case,
                               such as check for errors using ferror. */
    printf("%d, %s\n", chars_read, buffer);
}

あなたの別の質問に答えるために、'\0'int0なので、{'\0'}{0}同等です。

についてsetvbufは、私のドキュメントには次のように書かれています。

引数は、size通常どおり遅延最適サイズのバッファ割り当てを取得するためにゼロとして指定できます。

または\\の代わりにコメントするのはなぜですか?:-)///* */

編集:質問の編集に基づいて、sizeof("1")間違っている、sizeof(char)正しい。

sizeof("1")は2です。これは、が2つの要素を含む配列であるため"1"ですchar'1'0

于 2010-03-04T10:10:34.547 に答える
0

これは、リダイレクト./a.out<dataを使用してファイルから行をフレッドするバイトごとの方法です。

少なくとも期待される出力を生成します...:-)

/*

Why does this code not output the expected output ?,
http://stackoverflow.com/questions/2378264/why-does-this-code-not-output-the-expected-output

compile with:
gcc -Wall -O3 fread-test.c

create data:
echo $'1line\n2line\n3line\n4line' > data

./a.out < data

*/

#include <stdio.h>

#define SIZE 5

int main(void) 
{

   int i=0, countNL=0;
   char singlechar = 0;
   char linebuf[SIZE + 1] = {0};
   setvbuf(stdin, (char *)NULL, _IOFBF, sizeof(linebuf)-1);  

   while(fread(&singlechar, 1, 1, stdin))     // fread stdin byte-by-byte
   {
      if ( (singlechar == '\n') )
      {
         countNL++;
         linebuf[i] = '\0';
         printf("%d:  %s\n", countNL, linebuf);
         i = 0;
      } else {
         linebuf[i] = singlechar; 
         i++;
      }
   }

   if ( i > 0 )    // if the last line was not terminated by '\n' ...
   {
      countNL++;
      linebuf[i] = '\0';
      printf("%d:  %s\n", countNL, linebuf);
   }

 return 0;

}
于 2010-03-05T12:45:51.737 に答える
-1

char buffer [SIZE + 1] = {0};

これは期待どおりに機能していません。プログラムの定数データセグメントの1バイト領域をバッファポイントに設定しています。つまり、これによりSIZEのバイト数が破損し、メモリ保護障害が発生する可能性があります。C文字列は常にstrcpy()または同等のもので初期化してください。

于 2010-03-05T04:09:08.410 に答える