我正在尝试在基本的ubuntu gcc编译器中为基本的C类运行以下代码。
#include<stdio.h>
struct emp
{
int emp_num, basic;
char name[20], department[20];
};
struct emp read()
{
struct emp dat;
printf("\n Enter Name : \n");
scanf("%s", dat.name);
printf("Enter Employee no.");
scanf("%d", &dat.emp_num);
//printf("Enter department:");
//fgets(dat->department,20,stdin);
printf("Enter basic :");
scanf("%d", &dat.basic);
return dat;
}
void print(struct emp dat)
{
printf("\n Name : %s", dat.name);
printf("\nEmployee no. : %d", dat.emp_num);
//printf("Department: %s", dat.department);
printf("\nBasic : %d\n", dat.basic);
}
int main()
{
struct emp list[10];
for (int i = 0; i < 3; i++)
{
printf("Enter Employee data\n %d :\n", i + 1);
list[i] = read();
}
printf("\n The data entered is as:\n");
for (int i = 0; i < 3; i++)
{
print(list[i]);
}
return 0;
}
我希望名称接受空格。
当我输入结构的值时,问题出现了。我能够第一次输入名称,但后续迭代甚至没有提示我输入。
我尝试过使用fgets
,scanf("%[^\n]",dat.name)
甚至是gets()
(我很绝望),但每次都面临同样的问题。
第一个结构的输出很好,但剩下的就是垃圾,这个人的姓或只是空白。
有什么想法吗?
答案 0 :(得分:3)
使用scanf("%s")
读取字符串时,您正在读取第一个空格字符。这样,您的字符串不能包含空格。您可以改为使用fgets
,它会读取第一个换行符。
另外,为了刷新输入缓冲区,您可能需要使用例如scanf("%d\n")
而非scanf("%d")
。否则,后续fgets
将采用换行符,而不是要求您输入。
我建议您尝试使用一个小程序来读取第一个整数然后是一个字符串。你会明白我的意思,调试起来会容易得多。如果您遇到问题,我建议您发布一个新问题。
答案 1 :(得分:3)
问题是scanf("%[^\n",..
和fgets
不会跳过上一行读取可能遗留的任何空格。特别是,它们不会在最后一行的末尾跳过换行符,所以如果该换行符仍然在输入缓冲区中(当使用scanf("%d",..
读取最后一行时),那么{{ 1}}会在没有读取任何内容的情况下失败(在scanf
数组中留下随机垃圾),而name
只会读取换行符。
最简单的解决方法是在scanf中添加一个显式空格以跳过空格:
fgets
这也会跳过行开头的任何空格(和空白行),如果你想要一个以空格开头的名字,可能会出现问题。
注意我还添加了printf("\n Enter Name : \n");
scanf(" %19[^\n]", dat.name);
的长度限制以避免名称数组溢出 - 如果用户输入更长的名称,其余部分将保留在输入上并作为员工编号读取。您可能想跳过其余部分:
19
这将读取输入上留下的任何非换行符并将其丢弃。您可以将它与之前的scanf结合使用,为您提供如下代码:
scanf("%*[^\n]");
这将忽略某人在线路上输入的任何虚假额外内容,但仍会遇到有人输入预期数字或文件结束条件的字母的问题。要处理这些问题,您需要检查scanf的返回值。
答案 2 :(得分:0)
您尝试的是: -
scanf("%[^\n]",dat.name)
在此您忘记指定说明符。
你可以尝试使用它: -
scanf ("%[^\n]%*c", dat.name);
如果你想用空格阅读,请或fgets()
。
注意: - "%s"
将读取输入,直到到达空格。