繁体   English   中英

C 中二维字符数组的奇怪行为

[英]Bizarre behavior with 2D Char array in C

我得到了一些我不理解这段代码的奇怪行为:

for (int i = 0; i < 5; ++i) {
    scanf("%s", strings[i]);
}

for (int i = 0; i < 5; ++i) {
    printf("%s\n", strings[i]);
}

如果我输入 5 个字符串,例如:

this
is
a
test
help

我在第二个 for 循环中得到了这样的结果:

thisis
is
a
testhelp
help

知道发生了什么吗? 快把我逼疯了

所以 char 数组的工作方式是分配指定数组中的每个字符; 但是,最后一个字符是 null 字符,用于分隔“字符串”:

char str[4] = {'n','o','t','\0'};
char str[4] = {'t','h','i','s'};

因此,如果您添加的大小超过它的大小,因为它实际上节省了空间并且您的 scanf 工作正常。 因此,解决方案是,如果缓冲区是设定的大小,则将其增大一个大小,或者读取字符串,然后手动添加 null 字符

您的字符串的输入大小错误。

C 中的字符串以零结尾,这意味着它们将包含所需的内容和结尾的零字符(这样大多数 function 会理解您的字符串在哪里结束)。

您的数组将连续分配到堆栈上,这意味着在您的第一次循环之前,您的 memory 将如下所示:

000011112222333344445555

内容将是任意的,但为了便于理解,您的数组看起来像这样

  1. [[0,0,0,0],[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5]]
  2. [['t','h','i','s'],['\0',1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5]]
  3. [['t','h','i','s'],['i','s','\0',1][2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5]]

在连续视图中

't','h','i','s','i','s','\0',12222333344445555

导致观察到的行为

您可以通过 2 种方式解决问题

  • 通过使用 output 格式的%4s来限制字符串 output。
  • 将输入限制为 3 个字符%3s ,以便在写入终止零字符时输入不会重叠。
  • 增加字符串的大小以适应终止的零字符。

问题实际上在于您定义的字符数组。

"char strings[5][4]"

程序分配“字符串”20 个“字符”大小的 memory 块。

假设起始地址为 0x00,因此 memory 块从 0x00 到 0x20(为了便于理解以十进制表示)分配给“字符串”

这意味着 strings[0] 指向 0x00

这意味着 strings[1] 指向 0x04

这意味着 strings[2] 指向 0x08

这意味着 strings[3] 指向 0x12

这意味着 strings[4] 指向 0x16

现在在“scanf”中基本上是读取每个字符直到 endline 并将其存储在相应的 memory 块中

for (int i = 0; i < 5; ++i) {
    scanf("%s", strings[i]);
}

所以从你的问题来看,“this”存储在 4 个字符串块中 [0] 并且没有空格用于结束字符“is”占用字符串 [1] 中的 3 个字符,第三个字符是结束字符。

现在来到 arrays 的 printf function。它将数组视为指针并迭代直到找到 endline 语句。

for (int i = 0; i < 5; ++i) {
    printf("%s\n", strings[i]);
}

对于字符串[0],printf function 获取指针 0x00 和 iteartes 直到找到结束行字符(即在 0x06)

因此打印“thisis”,对于字符串 [1],指针位于 0x04,因此打印“is”。

现在,如果您输入的 sizw 字符串大于 4,您可以观察到该字符串溢出到下一个字符串

for (int i = 0; i < 1; ++i) {
                scanf("%s", strings[i]);
            }

for (int i = 0; i < 2; ++i) {
                printf("%s\n", strings[i]);
            }


**INPUT:**
        thisab

在上面的代码中,只有 strings[0] 被赋值为“thisab”,但它产生了 printf

**OUTPUT:**
                thisab
                ab

为避免此类问题,请使用字符串或将每行的大小定义为等于 (max_input_size+1)

暂无
暂无

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

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