【问题标题】:Trouble using char in scanf in a structure在结构中的 scanf 中使用 char 时遇到问题
【发布时间】:2014-12-20 01:09:41
【问题描述】:

我是一名学习 C 的学生,在使用结构和数组读取作为数组一部分的字符时似乎卡住了。

当我运行代码时,它会跳过 char scanf 并且不会读取任何字符。读取整数等没有问题。

例如(这是一个示例,我的代码要长得多,但我知道这里有问题)。读入名字的scanf部分是否正确?

struct stud s[5];
int i = 0;
for (int i = 0; i < 5; i++)
{
    fflush(stdout);
    s[i].no = i + 1;
    printf("\nStud number %d\n", s[i].no);
    printf("Enter name:");
    scanf_s("%c", &s[i].name);
    printf("Enter grade: ");
    scanf_s("%d", &s[i].grade);
    printf("Successfully added to grade book\n");
}

我在下面声明了它们:

struct stud {
    int no;
    char name;
    int grade;
};

如果有人能指出我正确的方向,那就太好了?

【问题讨论】:

  • 您预计会发生什么,而发生了什么?
  • 这一行:printf("输入姓名:");因为只会读取一个字符,可能应该是: printf("Enter first Letter of Name:");

标签: c arrays char structure


【解决方案1】:

您必须将name 声明为char 数组

struct room {
    int no;
    char name[32]; /* pick a reasonable size */
    int grade;
};

然后这个

scanf_s("%c",&s[i].name);

会变成

scanf_s("%s",s[i].name, _countof(s[i].name));

由于无法保证 name 的字符长度为 31,因此您必须像这样指定字段长度

scanf_s("%31s",s[i].name, _countof(s[i].name));

长度应该是sizeOfArray - 1,因为c字符串需要用一个空字节'\0'来标记字符串的结尾,而scanf_s会将该字节附加到读取的字符串中。

如果您没有指定字段长度,结果发现字符数超过了_countof(s[i].name) 请求的字符数,则不会读取任何内容,更多信息请阅读here

【讨论】:

  • 请注意,_countof() 不是标准 C(Microsoft 扩展),虽然 scanf_s() 在 C11 标准的 Annex K 中定义,但并未广泛实施(Microsoft 和通常不适用于类 Unix 系统)。
  • @JonathanLeffler:附件 K scanf_s 和 MS scanf_s 不兼容。 Annex K 版本的大小参数类型为size_t,MS 版本为int。在可变参数函数中。
  • @mafso:我希望我能说我是surprised。我知道snprintf_s() 的问题;我没有特别意识到scanf_s() 的问题。
  • _countof 的类型为int,而不是size_t,所以它等价于(int)(sizeof array/sizeof *array)_countof 适用于 MS scanf_ssizeof array/sizeof *array 适用于附件 K scanf_s(我不知道是否有通用平台实现它)。我的建议是根本不要使用这些功能。它们是不可移植的,几乎总是被错误地使用(在 SO 的问题和答案中,我还没有看到使用它们的实际代码),并且解决的标准函数的问题太少。
  • @mafso,好的,那么我把它留在 cmets 中还是我要修复答案?
【解决方案2】:

请注意,如果您想为学生输入超过 1 个字符,您应该创建一个合理大小的 char 数组并使用 @iharob 在他的回答中提到的 %s。如果您希望 name 成为 char,请更改

scanf_s("%c", &s[i].name);

scanf_s(" %c", &s[i].name, 1);

%c 之前的空格会跳过 stdin%c 中出现的各种空格(如换行符和空格),然后将扫描非空格字符。

【讨论】:

  • scanf_s(" %c") 需要以下 2 个参数
  • 我不知道!但是this site 没有提到 2 个论点。如果那个网站是错误的,那么scanf_s(" %c",&amp;s[i].name,1); 对吗?
  • A ms sample 使用 scanf_s("%4c", &amp;c, _countof(c)); 有很多关于使用 scanf_s 的细节,比如 _countof(c) 的类型。
  • 好的 - 我认为这是正确的方法,我记得一位讲师告诉我们:scanf_s(" %c", &s[i].name,1);
  • 如何在变量中添加一些东西,例如s[i].gradetotal = s[i].grade * 50;.它是否正确?谢谢!
【解决方案3】:

%c 不会出现字符,因为字符将出现在 stdin 中,您必须跳过字符。

scanf_s("%c", &s[i].name);

如果前面的最后一个字符是\n%c 将把\n 作为输入。 你要改代码,在%c前留一个空格就行了。

scanf_s(" %c", &s[i].name);

这将刷新stdin 中的空白字符并获取输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 2023-03-20
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2021-08-04
    相关资源
    最近更新 更多