21

fgets()は、EOFにすでに到達している場合でも、常にcharバッファーを\ 0で終了しますか?そのように見えますが(ANSI K&Rの本に示されている実装では確かにそうです)、確かにお願いしたいと思いました。

この質問は、gets()などの他の同様の関数にも当てはまると思います。

編集:「通常の」状況では\ 0が追加されることを知っています。私の質問は、EOFまたはエラー状態を対象としています。例えば:

FILE *fp;
char b[128];
/* ... */
if (feof(fp)) {
    /* is \0 appended after EACH of these calls? */
    fgets(b, 128, fp);
    fgets(b, 128, fp);
    fgets(b, 128, fp);
}
4

5 に答える 5

15

fgets常に読み取りバッファに「\0」を追加します。これによりsize - 1、ストリーム(size2番目のパラメータ)から最大で文字を読み取ります。

gets与えたバッファがオーバーフローしないことを保証できないため、絶対に使用しないでください。技術的には常に読み取り文字列を終了しますが、実際には役に立ちません。

于 2009-11-02T09:38:50.647 に答える
8

絶対に使用しないでください!!

    7.19.7.2fgets関数
    あらすじ
1 #include <stdio.h>
            char * fgets(char * limit s、int n、
                 FILE *ストリームを制限します);
    説明
2 fgets関数は、最大で1文字少ない文字を読み取ります
    ストリームによってポイントされたストリームからポイントされた配列へのnによって指定されます
    sによって。改行文字の後に追加の文字は読み取られません
    (保持されます)またはファイルの終わりの後。ヌル文字が書き込まれます
    配列に読み込まれた最後の文字の直後。
    戻り値
3 fgets関数は、成功するとsを返します。ファイルの終わりに遭遇した場合
    配列、配列の内容に文字が読み込まれていません
    変更されないままで、nullポインタが返されます。読み取りエラーが発生した場合
    操作中、配列の内容は不確定であり、nullです
    ポインタが返されます。

したがって、はいfgets()NULLを返さない場合、宛先配列は常にnull文字を持ちます。

fgets()NULLを返す場合、宛先配列が変更されている可能性があり、ヌル文字が含まれていない可能性があります。からNULLを取得した後は、配列に依存しないでくださいfgets()


編集例を追加

$ cat fgets_error.c
#include <stdio.h>

void print_buf(char * buf、size_t len){
  int k;
  printf( "%02X"、buf [0]);
  for(k = 1; k <len; k ++)printf( "%02X"、buf [k]);
}

int main(void){
  char buf [3] = {1、1、1};
  char * r;

  printf( "Ctrl + Dを入力:");
  fflush(stdout);
  r = fgets(buf、sizeof buf、stdin);
  printf( "\ nfgetsは%pを返し、bufは["、(void *)r);を返しました。
  print_buf(buf、sizeof buf);
  printf( "] \ n");

  0を返します。
}
$ ./a.out
Ctrl+Dを入力します。
fgetsが返され(nil)、bufには[01 01 01]
$

見る?bufにNULはありません:)

于 2009-11-02T09:42:36.593 に答える
4

man fgets:

fgets()は、ストリームから最大で1つ小さいサイズの文字を読み込み、sが指すバッファーにそれらを格納します。EOFまたは改行の後で読み取りが停止します。改行が読み取られると、バッファに格納されます。'\ 0'は、バッファの最後の文字の後に格納されます。

于 2009-11-02T09:42:26.543 に答える
2

バイナリ モード "rb" でファイルを開き、fgets を使用してテキストを 1 行ずつ読みたい場合は、次のコードを使用して、誤ってテキストに '\ 0' バイト。しかし、最後に述べたように、通常fgets、ストリームに '\0' が含まれている場合は使用しないでください。


size_t filepos=ftell(stream);
fgets(buffer, buffersize, stream);
len=strlen(buffer);
/* now check for > len+1 since no problem if the 
   last byte is 0 */
if(ftell(stream)-filepos > len+1) 
{
    if(!len) filepos++;
    if(!fseek(stream, filepos, SEEK_SET) && len)
    {
        fread(buffer, 1, len, stream);
        buffer[len]='\0';
    }
}
于 2015-08-15T11:54:54.017 に答える
1

はい、そうです。CPlusPlus.comから

ストリームから文字を読み取り、(num-1)文字が読み取られるか、改行またはファイルの終わりのいずれか早い方に到達するまで、C文字列としてstrに格納します。

改行文字はfgetsの読み取りを停止しますが、有効な文字と見なされるため、strにコピーされる文字列に含まれます。

C文字列の終わりを示すために読み取られた文字の後に、ヌル文字がstrに自動的に追加されます。

于 2009-11-02T09:38:34.743 に答える