繁体   English   中英

int 输出错误?

[英]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.

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