3

我正在尝试在基本 C 类的基本 ubuntu gcc 编译器中运行以下代码。

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

我希望名称接受空格。

当我将值输入结构时,问题就来了。我可以第一次输入名称,但随后的迭代甚至不会提示我输入。

我试过使用fgetsscanf("%[^\n]",dat.name)甚至gets()(我很绝望)但每次都面临同样的问题。

第一个结构的输出很好,但其余的要么是垃圾,要么是人的姓氏,要么是空白。

有任何想法吗?

4

3 回答 3

3

使用 读取字符串时scanf("%s"),您最多读取第一个空格字符。这样,您的字符串不能包含空格。您可以改用fgets它,它最多读取第一个换行符。

此外,为了刷新输入缓冲区,您可能需要使用 egscanf("%d\n")而不是scanf("%d"). 否则,后续fgets将采用换行符而不要求您输入。

我建议您尝试使用一个读取第一个整数然后读取字符串的小程序。你会明白我的意思,调试起来会容易得多。如果您对此有疑问,我建议您发布一个新问题。

于 2013-09-01T10:00:53.953 回答
3

问题是,scanf("%[^\n",..不要fgets跳过可能从前一行读取中留下的任何空白。特别是,它们不会跳过最后一行末尾的换行符,因此如果该换行符仍在输入缓冲区中(当最后一行被读取时scanf("%d",..),scanf则将失败而不读取任何内容(离开name数组中的随机垃圾),而fgets只会读取换行符。

最简单的解决方法是在 scanf 中添加一个显式空格以跳过空格:

printf("\n Enter Name : \n");
scanf(" %19[^\n]", dat.name);

这也将跳过行首的任何空格(和空白行),因此如果您希望名称以空格开头,则可能会出现问题。

注意我还添加了长度限制19以避免溢出名称数组——如果用户输入更长的名称,其余部分将留在输入中并被读取为员工编号。您可能想跳过该行的其余部分:

scanf("%*[^\n]");

这将读取输入中留下的任何非换行符并将它们丢弃。您可以将其与之前的 scanf 结合起来,为您提供如下代码:

printf("\n Enter Name : ");
scanf(" %19[^\n]%*[^\n]", dat.name);
printf("Enter Employee no. : ");
scanf("%d%*[^\n]", &dat.emp_num);
printf("Enter department : ");
scanf(" %19[^\n]%*[^\n]", dat.department);
printf("Enter basic : ");
scanf("%d%*[^\n]", &dat.basic);

这将忽略某人在一行中输入的任何虚假的额外内容,但仍然会在有人输入预期数字的字母或文件结尾条件时遇到问题。要处理这些,您需要检查 scanf 的返回值。

于 2013-09-01T20:12:49.417 回答
0

您尝试过的是:-

scanf("%[^\n]",dat.name)

在此您忘记指定说明符。

你可以尝试使用这个: -

scanf ("%[^\n]%*c", dat.name);

或者fgets()如果你想用空格阅读。

注意:-"%s"将读取输入,直到达到空白。

于 2013-09-01T10:02:23.603 回答