0

所以我正在编写一个小程序(我是 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. 如何防止用户输入大于 length 的值SYMBOL_MAX_LEN
  3. scanf 是否将空终止字符symbol自动放入,还是我需要手动执行?
4

3 回答 3

2

您可以限制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()对于这种类型的东西要好得多。

于 2013-10-20T15:20:24.367 回答
1

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

据我所知,没有。

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

通过使用缓冲区安全函数,如fgets.

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

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

于 2013-10-20T15:19:49.203 回答
1

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

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

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

不。

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

使用fgets.

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

是的

于 2013-10-20T15:17:27.567 回答