2016-11-11 8 views
6

私はスペースを含む場合も含まない場合もある文字列を読み込もうとしています。 "こんにちは世界"。ユーザーが入力した番号選択メニューで以下の操作を行います。これは私がやろうとしているものの小さなレプリカです。Cでスペースを含む文字列を読み取る

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

int main(void){ 
    char line[3][80]; 

    strcpy(line[0],"default line 1\n"); 
    strcpy(line[1],"default line 2\n"); 
    strcpy(line[2],"default line 3\n"); 

    for(int i = 0; i < 3; i++){ 
    printf("%s", line[i]); 
    } 

    int option = 0; 
    printf("would you like to replace line 1? (1 for yes)\n"); 
    scanf("%d",&option); 
    if(option==1){ 
    printf("what would you like to replace the line with?\n"); 
    fgets(line[0],strlen(line[0]),stdin); 
    } 

    for(int i = 0; i < 3; i++){ 
    printf("%s", line[i]); 
    } 
} 

なぜそれが私が行を変更するには、1を入力した後、それは私がそれを交換したいと自動的に空のように最初のもので、文字列を印刷し、その後何も入力しないでどうなるかを尋ねる文を印刷していることでしょうか?

私はすでにsscanf("%[^\n\t]s", line[0]);で行を読んでみました。何か案は?

+0

OPは問題に適用
char * s_gets(char *st, int n) { char *ret; int ch; ret = fgets(st, n, stdin); if (ret) { while (*st != '\n' && *st != '\0') ++st; if (*st) *st = '\0'; else { while ((ch = getchar()) != '\n' && ch != EOF) continue; // discard extra characters } } return ret; } 

、私はこのような何かを行う可能性がありますストリームの最初の文字として返されます。 –

+0

私は、 'scanf("%d "、&option)'と何か関係があると確信していますが、ユーザがその行を置き換えたいのかどうかを尋ねるときに、 – TheBoxOkay

+2

あなたの問題には直接関係しませんが、 'strlen(line [0])'は '80'に置き換えてください。バッファのサイズは、それに含まれる文字列の長さではなく、ここで '80 'であるバッファの全長です。 –

答えて

10

scanf("%d",&option); 

は、標準入力で\n文字を離れ、fgets()の最初の呼び出しによって消費されるからです。 だから、scanf()をC言語で完全に避けるのが最善です。

あなたはでそれを修正することができます:

scanf("%d",&option); 
    getchar(); /* consume the newline */ 

しかし、私は同様にoptionを読み取るために、その後、あなたは整数に変換するstrtol()を使用することができますfgets()を使用してお勧めしたいです。

この文は、あなたが意図したものではないことに注意してください(これは、あなたが読むことをline[0]に制限しています)。そう

fgets(line[0],sizeof line[0],stdin); 

あなたがline[0]の実際の大き件まで読むことができる:

fgets(line[0],strlen(line[0]),stdin); 

あなたは、おそらく使用することを意味しました。

だけでなくC FAQ項目をお読みください:http://c-faq.com/stdio/scanfprobs.html

+3

私が確認した 'scanf'はひどく、この種の問題はよくあることです。詳細については、Google _scanfはevil_(冗談なし)です。 –

+0

ありがとう、それは完璧に働いた! – TheBoxOkay

2

あなたの問題は'\n' charがstdinに左とfgetsによって消費されていることです。

私はそう

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

int main(void) 
{ 
    char line[3][80]; 
    char temp[3]; 

    strcpy(line[0],"default line 1\n"); 
    strcpy(line[1],"default line 2\n"); 
    strcpy(line[2],"default line 3\n"); 

    for(int i = 0; i < 3; i++){ 
     printf("%s", line[i]); 
    } 

    int option = 0; 
    printf("would you like to replace line 1? (1 for yes)\n"); 
    fgets(temp,sizeof(temp),stdin); 
    option = atoi(temp); 

    if(option==1){ 
     printf("what would you like to replace the line with?\n"); 
     fgets(line[0],sizeof(line[0]),stdin); 
    } 

    for(int i = 0; i < 3; i++){ 
    printf("%s", line[i]); 
    } 
} 
3

fgets()を使用するには、一般的にscanf()に絡み未満エラーが発生しやすいようだが、あなたは常に読み取り入力のfgetsを使用することをお勧めしたいユーザーは、限りある文字列を入力した場合または指定された最大文字数より長い場合、改行を含む余分な文字は入力ストリームに残ります。この理由から私は通常ユーザから入力文字列を得るために私自身のgets()のバージョンを書いています。数値入力が必要な場合はstrtol()を使います。ここでは、そのような関数の例である:私は `fgets`は、(ファイルの終わり)EOFを読むことを推測

#include <stdlib.h>    // for strtol() 

... 

char buf[80]; 
int option = 0; 

printf("would you like to replace line 1? (1 for yes)\n"); 
s_gets(buf, sizeof(buf)); 
option = strtol(buf, NULL, 10); 

if(option==1){ 
    printf("what would you like to replace the line with?\n"); 
    s_gets(line[0],sizeof(line[0])); 
} 
関連する問題