【问题标题】:String decleration length in CC中的字符串减值长度
【发布时间】:2013-10-20 15:15:39
【问题描述】:

所以我正在编写一个小程序(我是 C 新手,来自 C++),我想接收一个最大长度为 10 的字符串。

我声明一个字符数组为

#define SYMBOL_MAX_LEN 10 //Maximum length a symbol can be from the user (NOT including null character)
.
.
.
char symbol[SYMBOL_MAX_LEN + 1]; //Holds the symbol given by the user (+1 for null character)

那我用的时候为什么会这样:

scanf("%s", symbol); //Take in a symbol given by the user as a string

我可以输入“01234567890”,程序仍会存储整个值吗?

我的问题是:

  1. scanf 是否不会阻止将值记录在相邻的 symbol之后的内存块?
  2. 如何防止用户输入大于长度 SYMBOL_MAX_LEN 的值?
  3. scanf 是自动将空终止字符放入symbol,还是我需要手动执行?

【问题讨论】:

  • 通常编译器会将数组的大小填充为 4 的倍数以保持数据对齐,因此实际大小不是 11 而是 12。

标签: c char scanf


【解决方案1】:

您可以限制scanf() 的字符数,如下所示:

#include <stdio.h>

int main(void) {
    char buffer[4];
    scanf("%3s", buffer);
    printf("%s\n", buffer);
    return 0;
}

示例输出:

paul@local:~/src/c/scratch$ ./scanftest
abc
abc
paul@local:~/src/c/scratch$ ./scanftest
abcdefghijlkmnop
abc
paul@local:~/src/c/scratch$

scanf() 将为您添加终止 '\0'

如果您不想在格式字符串中硬编码长度,您可以动态构造它,例如:

#include <stdio.h>

#define SYMBOL_MAX_LEN 4

int main(void) {
    char buffer[SYMBOL_MAX_LEN];
    char fstring[100];
    sprintf(fstring, "%%%ds", SYMBOL_MAX_LEN - 1);
    scanf(fstring, buffer);
    printf("%s\n", buffer);
    return 0;
}

为免生疑问,scanf() 通常是用于处理输入的糟糕函数。 fgets() 更适合这种类型的东西。

【讨论】:

  • Paul,我认为在处理字符串时使用scanf 是个坏主意。
  • @hacks:我也认为scanf()是一个邪恶的功能,不过,这回答了问题,并且可以安全地完成。
【解决方案2】:

scanf 不会阻止值被记录在符号之后的相邻内存块中吗?

据我所知,没有。

如何防止用户输入大于长度 SYMBOL_MAX_LEN 的值?

通过使用像fgets这样的缓冲区安全函数。

scanf 是否会自动将空终止字符放入符号中,还是我需要手动执行?

仅当大小足以放置nul 终止符时。例如,如果您的数组长度为 10,并且您输入 10 个字符,它将如何放置 nul 终止符。

【讨论】:

  • fgets 是我想要的!谢谢。
【解决方案3】:

我可以输入“01234567890”,程序仍会存储整个值吗?

这是因为你不幸得到了你想要的结果。这将调用未定义的行为。

scanf 不会阻止值在符号之后记录在相邻的内存块中吗?

没有。

如何防止用户输入大于长度 SYMBOL_MAX_LEN 的值?

使用fgets

scanf 是否自动将空终止字符放入符号中,还是我需要手动执行?

是的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    相关资源
    最近更新 更多