Чтение в строке с пробелами в 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]);
}
}