【问题标题】:String Format Specifier outputs whole String even though char array size is limited [duplicate]即使字符数组大小有限,字符串格式说明符也会输出整个字符串 [重复]
【发布时间】:2021-06-15 05:22:34
【问题描述】:

以下是代码:

#include<stdio.h>
int main(){

    char a[6]; // DECLARATION OF ARRAY OF CHARACTER WITH SIZE 6
    printf("Enter ur Name :");
    scanf("%s",a); // INITILISATION OF ARRAY

    printf("\nName : %s\n",a); //PRITNTING WHAT GETS STORED IN A 

    for (int i = 0; i < 10; ++i)
    {
        printf("%c .",a[i]); // PRINTNING A WITHIN BOUND 10.
    }
    return 0;
}

我得到以下输出:

Enter ur Name :DESKTOP                      

Name : DESKTOP                    **//Why DESKTOP is being printed ? shouldn't be DESKTO**
D .E .S .K .T .O . . . . .                                                   

为什么我得到 DESKTOP .. 因为 a 大小为 6,因此 a 必须存储 DESKTO 。

【问题讨论】:

  • 访问越界元素是未定义的行为。 C 会让你这样做,但结果是不确定的——它可能会崩溃,可能会给出错误的值,甚至可能看起来“工作”。

标签: arrays c string format-specifiers


【解决方案1】:

scanf() 功能不适合胆小的人使用。研究文档很重要;例如https://en.cppreference.com/w/c/io/fscanf.

如果您希望它最多只能读取一定数量的字母,这是明智的,因为您刚刚发现的原因很明显(即 UB、缓冲区溢出漏洞、作品,请参阅 kaylum 的评论和链接),然后你需要明确告诉它这样做。

你可以这样做

scanf("%5s",a); /* five because of the unconditional terminator... */

要只读到允许的大小,5 +1 终止符。

这是必要的,因为简单的scanf("%s",a); 表示“不计后果地阅读,直到找到终止符;不要介意接收内存/数组的大小。”

按照建议进行更改,您的代码将获得所需的输出(少一个,否则增加数组大小并使用 6 个):

Enter ur Name :
Name : DESKT
D .E .S .K .T . . . . . .

它仍然有来自数组之外的奇怪输出(仍然是坏的 UB),但这是因为你的输出为 10,即太长了。

如果你也改成

char a[10]={'0','1','2','3','4','5','6','7','8','9'};

你会得到启发性的输出

Enter ur Name :
Name : DESKT
D .E .S .K .T . .6 .7 .8 .9 .

注意索引 5 处的不可见终止符。

或者使用scanf("%6s",a);(对于现在更大的数组来说可以):

Enter ur Name :
Name : DESKTO
D .E .S .K .T .O . .7 .8 .9 .

即你所期待的。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 2022-07-08
  • 1970-01-01
  • 2014-09-05
相关资源
最近更新 更多