2017-01-10 37 views
0

問題があります。私はいくつかの文字列の長さfgets関数を使用した後に見てみました。文字列内にできる文字数の下に文字列を入力すると(文字列の最大文字数が9で4文字を入力するなど)、文字列の長さが+1になります。どうして?改行文字'\n'の端がfgets()nameにコピーした文字列に含まれているため文字列の長さとfgets関数(C言語)

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(void) 
{ 
    char name[10]={0}; 
    printf("enter your name\n"); 
    fgets(name, 10, stdin); 
    printf("your name is %s and it is %d letters\n", name, strlen(name)); // length problem 

    return 0; 
} 
+1

'fgets'のmanページについては不明ですか?デバッガの関数の後に配列を調べましたか?あなたは文字列の最後に何を見つけましたか? – Olaf

+2

'fgets()'は改行を読み込んだ場合、改行を入力に含めます。 –

+0

...名前の後に出力が**次の行に移動する** ... – LPs

答えて

3

のfgets()は、バッファにそれらをストリームからsize文字未満で、ほとんど1で読み込み、 店舗sが指します。読み取りは、 EOFまたは改行の後に停止します。改行が読み取られた場合、改行はバッファに格納されます。 バッファー の最後の文字の後に終端ヌルバイト(aq \ 0aq)が格納されます。

したがって、string_length+1を返すと、4文字後に'\n'が追加されます。

Removing trailing newline character from fgets() inputから@TimČasソリューションをコードに追加できます。

行はまだfgets()関数で改行文字を削除した後で読み込まれます。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


int main(void) 
{ 
    char name[10] = { 0 }; 
    printf("enter your name\n"); 
    fgets(name, 10, stdin); 
    printf("your name is %s and it is %d letters\n", name, strlen(name)); // length problem 
    name[strcspn(name, "\n")] = 0; 
    printf("NEW - your name is %s and it is %d letters\n", name, strlen(name)); 
    return 0; 
} 

その出力:文字配列は、十分なスペースを持っている

enter your name 
Andy 
your name is Andy 
and it is 5 letters 
NEW - your name is Andy and it is 4 letters 
Press any key to continue . . . 
+0

それは追加する新しい行なしで文字列を取得するにはどうすればいいですか?(関数がそれを追加すると ''\ n'を削除しますか?) –

+0

私は答えを更新しました。 – jgorosdev

+0

[@LPs%zu](http://stackoverflow.com/questions/41572713/string-length-with-fgets-function-in-c#comment70350205_41572713) – chux

1

場合、標準関数fgetsはまた、通常、入力されたキー入力に対応し、アレイ内の改行文字を含んでいます。

あなたが機能strlenを適用した期待される結果を得るでしょう、その後あなたがこの冗長改行文字以下の方法

name[strcspn(name, "\n")] = '\0'; 

を削除することができます。 man fgetsで書かれているよう

1

関数fgets()関数は、指定されたストリームと文字列 STRに格納してからサイズによって指定された文字 の数よりも多くても1つ以下で読み取ります。改行文字がファイルの終わりに見つかるか、 エラーが発生すると、読み込みが停止します。改行があれば、それが保持されます。いずれかの文字が読み込まれ、 にエラーがなければ、文字列の終わりに `\ 0 '文字が追加されます。あなたはstdinから読んでいるので

は、fgets(name, 10, stdin)は標準入力バッファから最大で9つの文字を読み取り、最後に\0を追加します。ユーザーがEnterキーを押したときに生成された改行文字\nがバッファにも入っているだけです。

脇役として、fgetsに渡される配列のサイズを指定するときは、sizeof()を使用することが慣習的です(そして良い方法です)。

fgets(name, (int) sizeof(name), stdin); 
+1

を参照してください。*間違ってはなりません!*確かに、そのマシンとして、しかし、それはまだ*間違って使用することができます。配列の代わりにポインタとして使うイメージング: 'char * readstr(char * p){return fgets(p、sizeof p、stdin);} } '(ほとんどのシステムで)4または8の' char'を読み込もうとします。 – alk

+0

「間違ってはいけない! sizeofは型 'size_t'を返しますが、' fgets(char * s、int n、FILE * stream) 'はサイズに' int'を使います。巨大な配列では、これは予期せずに変換される可能性があります。確かにまれですが、_never_ではありません。 – chux

+0

戻り値がチェックされていないと、それが間違ってしまうことはありません。 'fgets'は' EOF'が出たら 'stdin'から' NULL'を返すことができます。 – RoadRunner