无法正常输入带空格的字符串
我想要实现的功能是一次输入图书的书名、id、时间等等和图书简介(带空格的字符串)。尝试了:
1.scanf()里面用%s。缺点是不能输入空格
2.get()
3.fgets()
2和3的共同缺点是,在运行时,刚输出完introduction:那一行后,程序好像直接跳过了输入的语句,开始输出下面的内容。
下面是源代码的部分内容:
p = (struct bookstruct*)malloc(sizeof(struct bookstruct));
strcpy(p->bookname, bookname);
printf("ISDN ");//add
scanf("%d", &p->id);
printf("author: ");
scanf("%s", p->author);
printf("bookyear: ");
scanf("%d", &p->year);
printf("bookmonth: ");
scanf("%d", &p->month);
printf("bookcount: ");
scanf("%d", &p->count);
printf("price: ");
scanf("%d", &p->price);
printf("press:");
scanf("%s", p->press);
printf("introduction: ");//需要允许输入一长串英文文章(带空格的字符串)
/*三种输入方法都不行:*/
//gets(p->intro);
//scanf("%s", p->intro);//不允许输入空格
fgets(p->intro, 100, stdin);//100是char intro的长度
bookend->next = p;
bookend = p;
bookend->next = NULL;
该回答引用ChatGPT4与博主@晓码自在合作编写:
你遇到的问题是,C语言的scanf()和fgets()在读取带空格的字符串时的问题。原因是:
scanf()在读取%s格式时,遇到空格、回车等会停止读取。
fgets()在读取时,输入的字符串包含空格,那么空格之后输入的内容会作为下一次输入读取。
要解决这个问题,有两种常用的方法:
c
char intro[100];
fgets(intro, 100, stdin);
sscanf(intro, "%s", p->intro);
c
char intro[100];
fgets(intro, 100, stdin);
char *token = strtok(intro, " ");
strcpy(p->intro, token);
这里strtok()使用空格" "作为分割符,将intro字符串分割,获取第一个token,即书名字符串,存储到p->intro中。
所以你的代码可以修改为:
c
printf("introduction: ");
char intro[100];
fgets(intro, 100, stdin);
char *token = strtok(intro, " ");
strcpy(p->intro, token);
使用fgets()读取字符串,然后strtok()获取需要的部分,这样就可以解决读取带空格字符串的问题了。
strtok()每次调用会获取字符串的下一个token,所以如果需要获取字符串中的多个空格分隔的词,可以多次调用strtok()。
你可以尝试着使用fgets()函数来输入带空格的字符串,但是需要注意以下几点:
fgets()函数会将输入的换行符\n也读入缓冲区,在使用输入字符串时需要将其去除。
输入的字符串长度可能会超过您指定的缓冲区大小,所以需要对输入字符串的长度进行检查,如果超出了缓冲区大小,则需要将缓冲区扩大。
以下是优化后的代码(仅供参考):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_INTRO_LEN 1000 // 输入的字符串最大长度
typedef struct bookstruct{
char bookname[100];
int id;
char author[100];
int year;
int month;
int count;
int price;
char press[100];
char *intro;
struct bookstruct *next;
} Book;
int main() {
Book *p, *bookend;
bookend = p = (Book*)malloc(sizeof(Book));
printf("bookname: ");
fgets(p->bookname, 100, stdin);
if (strlen(p->bookname) > 0 && p->bookname[strlen(p->bookname)-1] == '\n') {
p->bookname[strlen(p->bookname)-1] = '\0'; // 去除输入的换行符
}
printf("ISDN: ");
scanf("%d", &p->id);
fflush(stdin); // 清空输入缓冲区
printf("author: ");
scanf("%s", p->author);
fflush(stdin); // 清空输入缓冲区
printf("bookyear: ");
scanf("%d", &p->year);
fflush(stdin); // 清空输入缓冲区
printf("bookmonth: ");
scanf("%d", &p->month);
fflush(stdin); // 清空输入缓冲区
printf("bookcount: ");
scanf("%d", &p->count);
fflush(stdin); // 清空输入缓冲区
printf("price: ");
scanf("%d", &p->price);
fflush(stdin); // 清空输入缓冲区
printf("press: ");
scanf("%s", p->press);
fflush(stdin); // 清空输入缓冲区
printf("introduction: ");
char* intro = malloc(MAX_INTRO_LEN);
fgets(intro, MAX_INTRO_LEN, stdin);
if (strlen(intro) > 0 && intro[strlen(intro)-1] == '\n') {
intro[strlen(intro)-1] = '\0'; // 去除输入的换行符
}
p->intro = intro;
bookend->next = p;
bookend = p;
bookend->next = NULL;
//...
return 0;
}
如果使用fgets()函数输入带空格的字符串后,程序继续执行而不等待您的输入,则可能是由于在输入其它内容时,输入缓冲区中还有残留的换行符导致的。您可以在使用fgets()函数前清空输入缓冲区;
fflush(stdin); // 清空输入缓冲区
fgets(intro, MAX_INTRO_LEN, stdin);
可以考虑使用fgets()函数来实现包含空格的字符串输入。具体的步骤如下:
char str[100]; // 定义字符数组变量
fgets(str, 100, stdin); // 使用fgets()函数来读取用户输入的字符串
但是需要注意输入缓冲区的大小,尽可能保证其能够容纳用户输入的字符串。在上面的代码中,输入缓冲区的大小为100。
fgets()函数会读取用户输入的字符串到缓冲区中,但是会把输入的回车符也一起读取,因此需要在读取字符串后去掉最后的回车符。
str[strlen(str) - 1] = '\0'; // 去掉字符串末尾的回车符
scanf("%d", &num); // 使用scanf()函数来读入用户输入的数字
getchar(); // 吸收输入缓冲区中的回车符
fflush(stdin); // 清空输入缓冲区
完整的代码示例如下:
#include <stdio.h>
#include <string.h>
int main()
{
int num;
char str[100];
printf("请输入一个数字:");
scanf("%d", &num);
getchar(); // 吸收输入缓冲区中的回车符
printf("请输入一行文本:");
fgets(str, 100, stdin);
str[strlen(str) - 1] = '\0'; // 去掉字符串末尾的回车符
printf("您输入的数字是:%d\n", num);
printf("您输入的文本是:%s\n", str);
fflush(stdin); // 清空输入缓冲区
return 0;
}
这么改,供参考:
p = (struct bookstruct*)malloc(sizeof(struct bookstruct));
strcpy(p->bookname, bookname);
printf("ISDN ");//add
scanf("%d", &p->id);
getchar();
printf("author: ");
scanf("%s", p->author);
getchar();
printf("bookyear: ");
scanf("%d", &p->year);
getchar();
printf("bookmonth: ");
scanf("%d", &p->month);
getchar();
printf("bookcount: ");
scanf("%d", &p->count);
getchar();
printf("price: ");
scanf("%d", &p->price);
getchar();
printf("press:");
scanf("%s", p->press);
getchar();
printf("introduction: ");//需要允许输入一长串英文文章(带空格的字符串)
scanf("%[^\n]", p->intro); // 用scanf()输入带空格的字符串,直到遇到回车换行符结束
/*三种输入方法都不行:*/
//gets(p->intro);
//scanf("%s", p->intro);//不允许输入空格
//fgets(p->intro, 100, stdin);//100是char intro的长度
bookend->next = p;
bookend = p;
bookend->next = NULL;