出自《C Primer Plus》一书 4.2.2 String 我正在使用 MAC Xcode 亲自尝试示例代码。
这是代码:
#include <stdio.h>
#define PRAISE "You are an extraordinary being."
int main(void)
{
char name[1];
printf("What\'s your name?\n");
scanf("%s", name);
printf("Hello, %s. %s\n", name, PRAISE);
return 0;
}
当我输入“aaaaaaaaaaaaaa”,共13个字母时,屏幕显示:
libdyld.dylib`dyld3::MachOFile::forEachLoadCommand:
0x7fff697aa8a8 <+0>: pushq %rbp
0x7fff697aa8a9 <+1>: movq %rsp, %rbp
0x7fff697aa8ac <+4>: pushq %r15
0x7fff697aa8ae <+6>: pushq %r14
0x7fff697aa8b0 <+8>: pushq %r13
0x7fff697aa8b2 <+10>: pushq %r12
0x7fff697aa8b4 <+12>: pushq %rbx
0x7fff697aa8b5 <+13>: subq $0x28, %rsp
0x7fff697aa8b9 <+17>: movb $0x0, -0x29(%rbp)
0x7fff697aa8bd <+21>: movq %rdx, %r12
0x7fff697aa8c0 <+24>: movq %rsi, %rbx
0x7fff697aa8c3 <+27>: movq %rdi, %r15
-> 0x7fff697aa8c6 <+30>: movl (%r15), %edx
0x7fff697aa8c9 <+33>: cmpl $0xfeedface, %edx ;
imm = 0xFEEDFACE
0x7fff697aa8cf <+39>: je 0x7fff697aa8e3 ;
<+59>
0x7fff697aa8d1 <+41>: cmpl $0xfeedfacf, %edx ;
imm = 0xFEEDFACF
Diagnostics::error(char const*, ...)
0x7fff697aa9a2 <+250>: addq $0x10, %rsp
0x7fff697aa9a6 <+254>: addq $0x28, %rsp
0x7fff697aa9aa <+258>: popq %rbx
0x7fff697aa9ab <+259>: popq %r12
0x7fff697aa9ad <+261>: popq %r13
0x7fff697aa9af <+263>: popq %r14
0x7fff697aa9b1 <+265>: popq %r15
0x7fff697aa9b3 <+267>: popq %rbp
0x7fff697aa9b4 <+268>: retq
为了简单起见,我省略了上面的一些代码。
如果我输入更多字母,比如20个“a”, 它返回:错误:0x7fff00616000 的内存读取失败
如果我将第五行更改为: 字符名称[2];
并输入14个字符,返回相同的结果。
同样, 如果我将第五行更改为: 字符名称[3];
并输入15个字符,返回相同的结果。
我知道这与aaray的大小有关,但是,我不知道括号中的数字是如何连接到相应的输入字符数的。谁能详细解释一下吗?
最佳答案
char name[1];
仅足以存储单个字符。如果您尝试向其中存储超过 1 个字符,则剩余的字符将在数组末尾写入内存,这可能会覆盖“重要”数据,从而导致崩溃(或更糟糕的是,会损坏其他地方使用的数据)。
字符串是包含 0 值终止符的字符值序列。如果要存储 N
字符字符串,则需要分配一个至少 N
+ 的数组1 个元素宽。因此,如果您想在name
中存储最多13个字符的字符串,那么您需要将其声明为
char name[14]; // +1 to hold the string terminator
仍然有可能向字符串写入比其容纳大小更多的字符,因此您需要在输入方面小心。 scanf
允许您指定要读取的最大字符数:
scanf( "%13s", name ); // at most 13 characters read into name
不幸的是,该字段宽度不能用参数指定(就像在 printf
中那样)。另一种选择是根本不使用 scanf
,而是使用 fgets
:
fgets( name, sizeof name, stdin );
fgets
将从 stdin
读取不超过 sizeof name
- 1 个字符并将其写入 name
,然后将 0 终止符添加到 name
的末尾。 sizeof name
计算出name
中的字节数。
关于char name[1],但是当我输入 13 个字符时,屏幕上会发生奇怪的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56652585/