[英]Wrong int outputted?
#include <stdio.h>
int main(){
int age;
char name[] ="";
printf("enter your age: ");
scanf("%d", &age);
printf("enter your name: ");
scanf("%s", &name);
printf("your name is %s and you are %d years old.",name, age);
return 0;
}
例如,如果我将年龄设置为“20”并将名称设置为“name”,它会输出以下内容:
你的名字是名字,你今年 6647137 岁。
为什么说“6647137”年而不是 20 年?
char name[] ="";
您没有正确定义name
。
#define MAX_NAME_LENGTH 100
char name[MAX_NAME_LENGTH+1];
定义它不完整然后完成它你让它指向某个区域,在这个区域可能有其他变量围绕着定义字符串文字的数组,或者字符串文字甚至可以在 RO memory 中,从而无法写入。 尝试在字符串文字的指针处写入是未定义的行为(6.4.5.p6 字符串文字,第 63 页)。
您覆盖了name
太短的字符数组。
它目前的大小为 1,仅包含终止符'\0'
。
在许多环境中,您奇怪的年龄值可以通过第一个受害者 integer 来解释。
确保使用足够大的数组。
此外,强烈建议使用scanf()
的高级功能来避免缓冲区溢出。
请阅读文档:
https://en.cppreference.com/w/c/io/fscanf
这篇文章可能会很有帮助:
http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
快学这个,学好这个:C没有一流的“字符串”类型!
当你写的
char name[] = "";
你没有声明一个字符串变量,它最初包含一个空字符串,但它可以并且会自动扩展以包含你试图分配给它的任何字符串。
不,您得到的是一个大小正好为 1 的char
数组,最初包含空字符串,正好(且仅)由字符串终止字符'\0'
组成。 这个数组不能用于任何事情:它唯一能够包含的是空字符串,因为它没有(也永远不会)有空间容纳更多的东西。
在 C 中,通常您有责任了解您的字符串将有多大,并显式分配每个变量以引用足够的 memory 来表示它可能包含的任何字符串。
例如,你可以写
char name[11] = "";
现在你要说的是,“给我一个字符数组,足以包含最多 10 个字符长的字符串(加上 1 作为终止\0
字符),最初包含空字符串。”
现在你可以放心地说
scanf("%s", name);
但还有两点需要说明。
首先,您会注意到我省略了&
。 您可能有这样的印象,即在调用scanf
时始终需要变量上的&
。 这是一个真正的规则,但它有一个例外:事实证明,当您使用%s
将字符串读入数组时,您不需要&
。 有时错误是无害的(代码会碰巧工作),但有时它会导致问题(例如当您使用%s
读入指针变量指向的数组时)。 我的编译器警告我warning: format specifies type 'char *' but the argument has type 'char (*)[1]'
when I do something when I do this.
但其次,如果我们已经声明
char name[11] = "";
,那么我们如何实际执行呢? 我们如何安排我们或我们控制较少的 function 之类的scanf
,不会意外地尝试向我们的name
数组写入超过 10 个字符?
正如我们已经看到的,如果你只是打电话
scanf("%s", name);
你得不到任何保护。 scanf
将读取与用户键入的字符一样多的字符,直到它看到换行符或其他空格,它会将所有这些字符写入您提供的变量,如果字符多于变量可以容纳的字符数,那么糟糕的事情就会发生。
防止这种情况的一种方法是给scanf
限制它可以读取的字符数:
scanf("%10s", name);
现在,通过将10
放在那里,您告诉scanf
不要读取长度超过 10 个字符的字符串,这样它就不会溢出您的name
数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.