简体   繁体   English

使用scanf()输入字符串

[英]inputting a character string using scanf()

I started learning about inputting character strings in C. In the following source code I get a character array of length 5. 我开始学习有关在C语言中输入字符串的信息。在以下源代码中,我得到了一个长度为5的字符数组。

#include<stdio.h>
int main(void)
{
    char s1[5];
    printf("enter text:\n");
    scanf("%s",s1);
    printf("\n%s\n",s1);
    return 0;

}

when the input is: 当输入为:

  1. 1234567891234567 , and I've checked it's working fine up to 16 elements(which I don't understand because it is more than 5 elements). 1234567891234567 ,并且我检查了它最多可以正常工作16个元素(我不明白,因为它超过5个元素)。
  2. 12345678912345678 , it's giving me an error segmentation fault: 11 (I gave 17 elements in this case) 12345678912345678 ,这给了我一个错误segmentation fault: 11 (在这种情况下,我给出了17个元素)
  3. 123456789123456789 , the error is Illegal instruction: 4 (I gave 18 elements in this case) 123456789123456789 ,错误是Illegal instruction: 4 (在这种情况下,我给出了18个元素)

I don't understand why there are different errors. 我不明白为什么会有不同的错误。 Is this the behavior of scanf() or character arrays in C?. 这是scanf()还是C中的字符数组的行为? The book that I am reading didn't have a clear explanation about these things. 我正在阅读的书对此没有明确的解释。 FYI I don't know anything about pointers. 仅供参考,我对指针一无所知。 Any further explanation about this would be really helpful. 关于此的任何进一步解释将非常有帮助。

Is this the behavior of scanf() or character arrays in C? 这是scanf()还是C中字符数组的行为?

TL;DR - No, you're facing the side-effects of undefined behavior . TL; DR-不,您正面临不确定行为的副作用。

To elaborate, in your case, against a code like 在您的情况下,针对类似

 scanf("%s",s1);

where you have defined 您定义的位置

 char s1[5];

inputting anything more than 4 char will cause your program to venture into invalid memory area (past the allocated memory) which in turn invokes undefined behavior . 输入超过4个char任何内容将使您的程序进入无效的内存区域(过去分配的内存),从而调用未定义的行为

Once you hit UB, the behavior of the program cannot be predicted or justified in any way. 一旦打到UB,就无法以任何方式预测或证明程序的行为。 It can do absolutely anything possible (or even impossible). 它可以做任何可能的事情(甚至是不可能的事情)。

There is nothing inherent in the scanf() which stops you from reading overly long input and overrun the buffer, you should keep control on the input string scanning by using the field width, like scanf()没有内在的本质,它可以阻止您读取过长的输入并溢出缓冲区,您应该使用字段宽度来控制输入字符串的扫描,例如

 scanf("%4s",s1);  //1 saved for terminating null

The scanf function when reading strings read up to the next white-space (eg newline, space, tab etc.), or the "end of file". 读取字符串时, scanf函数将读取下一个空格(例如,换行符,空格,制表符等)或“文件结尾”。 It has no idea about the size of the buffer you provide it. 知道您提供的缓冲区的大小。

If the string you read is longer than the buffer provided, then it will write out of bounds, and you will have undefined behavior . 如果您读取的字符串比提供的缓冲区长,那么它将超出范围,并且您将具有undefined behavior

The simplest way to stop this is to provide a field length to the scanf format, as in 停止此操作的最简单方法是为scanf格式提供字段长度,如

char s1[5];
scanf("%4s",s1);

Note that I use 4 as field length, as there needs to be space for the string terminator as well. 请注意,我使用4作为字段长度,因为字符串终止符也需要有空间。

You can also use the "secure" scanf_s for which you need to provide the buffer size as an argument: 您还可以使用需要提供缓冲区大小的“安全” scanf_s作为参数:

char s1[5];
scanf_s("%s", s1, sizeof(s1));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM