Чтение в строке с пробелами в C

Я пытаюсь прочитать строку, которая может включать или не включать пробелы ex. "Привет, мир". Выполните следующие действия с помощью меню выбора номера, которое вводится пользователем. Это всего лишь маленькая копия того, что я пытаюсь сделать.

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

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

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

  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("%[^nt]s", line[0]); без каких-либо удачи. Есть идеи?

3 ответов


потому что

scanf("%d",&option);

оставляет \n символ в stdin и потребляется при первом вызове fgets(). Вот почему лучше избегать scanf() в C полностью.

вы можете исправить это с:

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

но я бы предложил использовать fgets() читать option, а затем вы можете использовать strtol() чтобы преобразовать его в целое число.

обратите внимание, что это утверждение, вероятно, не то, что вы намеревались (что ограничивает то, что вы можете прочитать в line[0]).

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

вы, вероятно, хотели использовать:

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

так что вы можете прочитать до фактического размера line[0].

пожалуйста, прочитайте запись c Faq, а также:http://c-faq.com/stdio/scanfprobs.html


используя fgets() обычно кажется менее подверженным ошибкам, чем запутывание с scanf(), но если пользователь вводит строку, которая длиннее или длиннее максимального количества указанных символов, любые дополнительные символы до и включая новую строку остаются во входном потоке. По этой причине я обычно пишу свою версию gets() чтобы получить входные строки от пользователя, и если я хочу числовой ввод, я использую strtol(). Вот пример такой функции:

char * s_gets(char *st, int n)
{
    char *ret;
    int ch;

    ret = fgets(st, n, stdin);
    if (ret) {
        while (*st != '\n' && *st != '')
            ++st;
        if (*st)
            *st = '';
        else {
            while ((ch = getchar()) != '\n' && ch != EOF)
                continue;           // discard extra characters
        }
    }
    return ret;
}

в случае OPs проблема, я мог бы сделать что-то вроде этого:

#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]));
}

ваша проблема в том, что '\n' char остается в stdin и потребил путем fgets.

Я бы посоветовал вам всегда использовать 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]);
    }
}