在 C 中读入带空格的字符串
Reading in a string with spaces in C
我正在尝试读入可能包含或不包含空格的字符串,例如。 "hello world"。通过使用用户输入的数字 select 菜单执行以下操作。这只是我正在尝试做的事情的一个小副本。
#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]);
的行,但没有任何运气。有什么想法吗?
因为
scanf("%d",&option);
将 \n
字符留在标准输入中,并在第一次调用 fgets()
时使用。
这就是为什么最好完全避免在 C 中使用 scanf()
。
您可以通过以下方法修复它:
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 常见问题条目:http://c-faq.com/stdio/scanfprobs.html
您的问题是 '\n'
字符留在 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]);
}
}
使用 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 != '[=10=]')
++st;
if (*st)
*st = '[=10=]';
else {
while ((ch = getchar()) != '\n' && ch != EOF)
continue; // discard extra characters
}
}
return ret;
}
应用于OP问题,我可能会这样做:
#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]));
}
我正在尝试读入可能包含或不包含空格的字符串,例如。 "hello world"。通过使用用户输入的数字 select 菜单执行以下操作。这只是我正在尝试做的事情的一个小副本。
#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]);
的行,但没有任何运气。有什么想法吗?
因为
scanf("%d",&option);
将 \n
字符留在标准输入中,并在第一次调用 fgets()
时使用。
这就是为什么最好完全避免在 C 中使用 scanf()
。
您可以通过以下方法修复它:
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 常见问题条目:http://c-faq.com/stdio/scanfprobs.html
您的问题是 '\n'
字符留在 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]);
}
}
使用 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 != '[=10=]')
++st;
if (*st)
*st = '[=10=]';
else {
while ((ch = getchar()) != '\n' && ch != EOF)
continue; // discard extra characters
}
}
return ret;
}
应用于OP问题,我可能会这样做:
#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]));
}