2016-04-07 81 views
1

我开始学习中C.输入字符串在下面的源代码我得到长度5.使用scanf的输入字符串()

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

} 

的字符数组当输入为:

  1. 1234567891234567,我检查了它的工作正常多达16个元素(我不明白,因为它超过5个元素)。
  2. 12345678912345678,它给我一个错误segmentation fault: 11(我给在这种情况下,17种元素)
  3. 123456789123456789,错误被Illegal instruction: 4(我给在这种情况下,18种元素)

我不明白为什么有不同的错误。这是C中的scanf()或字符数组的行为。我正在阅读的这本书对这些事情没有一个明确的解释。仅供参考我不了解指针。任何进一步的解释都会很有帮助。

+1

的行为*不确定*当输入的长度超过4个字符。 *未定义的行为*并不意味着“必须立即崩溃”,这意味着语言没有义务做任何特别的事情。 – EOF

+0

但是当输入超过5个字符时它不应该给我一个错误? – yash

+0

@buggenerator:这不是违反约束条件,编译器没有义务发出诊断消息,也没有要求在运行时引发错误。 – EOF

回答

5

这是scanf()或C中的字符数组的行为吗?

TL; DR - 不,您正面临undefined behavior的副作用。

为了阐述,在你的情况,针对类似的代码

scanf("%s",s1); 

,你必须定义

char s1[5]; 

输入任何超过4 char会导致你的计划进军无效的内存区(通过分配的内存),然后调用undefined behavior

一旦你击中UB,程序的行为无法以任何方式预测或证明。它可以做任何事情(甚至不可能)。

没有什么其中阻止你读取过长输入和溢出缓冲器中的scanf()固有的,则应通过使用场宽度保持在输入字符串扫描控制,如

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

但是它怎么样可以达到16个字符,而且比给我错误还有'不同的错误'更好? – yash

+0

阅读[未定义行为](https://en.wikipedia.org/wiki/Undefined_behavior)。也请查看最新的答案以进行澄清。 –

+2

下一次你编译和运行,它可能会接受高达128或可能在第6次崩溃,你永远不会知道... –

2

scanf功能当读取字符串时读入下一个空格(例如换行符,空格,制表符等)或“文件结尾”。它有没有有关您提供的缓冲区大小的想法。

如果您读取的字符串比提供的缓冲区长,那么它会写出界限,并且您将有未定义的行为

停止这种最简单的方法是提供一个字段长度为scanf格式,如

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

请注意,我用4作为字段长度,因为需要为一个字符串结束的空间好。

您还可以使用“安全” scanf_s在您需要提供的缓冲区大小作为参数:

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

我不是故意在这里天真。这是否意味着在这种情况下缓冲区是16个字符? – yash

+1

@buggenerator否缓冲区的长度是您声明变量时提供的长度_you_。所以这里的长度是5.(char s1 [** 5 **]) –

+0

@buggenerator“缓冲区大小”是您声明的数组的大小(可能会减去终止符的大小)。 –

相关问题