C语言 printf("%s", char*) 什么时候停止打印?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2726301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:18:17  来源:igfitidea点击:

When does printf("%s", char*) stop printing?

cprintf

提问by user327406

In my class we are writing our own copy of C's malloc() function. To test my code (which can currently allocate space fine) I was using:

在我的课堂上,我们正在编写自己的 C 语言 malloc() 函数副本。为了测试我的代码(目前可以很好地分配空间),我使用了:

char* ptr = my_malloc(6*sizeof(char));
memcpy(ptr, "Hello\n", 6*sizeof(char));
printf("%s", ptr);

The output would typically be this:

输出通常是这样的:

Hello
Unprintable character

Some debugging figured that my code wasn't causing this per se, as ptr's memory is as follows:

一些调试认为我的代码本身并没有导致这种情况,因为 ptr 的内存如下:

[24 bytes of meta info][Number of requested bytes][Padding]

[24 字节元信息][请求的字节数][填充]

So I figured that printf was reaching into the padding, which is just garbage. So I ran a test of: printf("%s", "test\nd");and got:

所以我认为 printf 进入了填充,这只是垃圾。所以我运行了一个测试: printf("%s", "test\nd");并得到:

test
d

Which makes me wonder, when DOES printf("%s", char*) stop printing chars?

这让我想知道,什么时候 printf("%s", char*) 停止打印字符?

回答by James McNellis

It stops printing when it reaches a null character (\0), because %sexpects the string to be null terminated (i.e., it expects the argument to be a C string).

它在遇到空字符 ( \0)时停止打印,因为%s期望字符串以空结尾(即,它期望参数是 C 字符串)。

The string literal "test\nd"is null terminated (all string literals are null terminated). Your character array ptris not, however, because you only copy six characters into the buffer (Hello\n), and you do not copy the seventh character--the null terminator.

字符串文字"test\nd"以空结尾(所有字符串文字都以空结尾)。ptr但是,您的字符数组不是,因为您只将六个字符复制到缓冲区 ( Hello\n) 中,而您没有复制第七个字符——空终止符。

回答by David Gelhar

James is correct about printf stopping when it gets to the null character, and Uri is correct that you need to allocate a 7-character buffer to hold "hello\n".

James 关于 printf 在到达空字符时停止是正确的,而 Uri 是正确的,您需要分配一个 7 个字符的缓冲区来保存“hello\n”。

Some of the confusion with terminators would be mitigated if you used the usual C idiom for copying a string: strcpy(ptr, "Hello\n"), rather than memcpy.

如果您使用通常的 C 习语来复制字符串:strcpy(ptr, "Hello\n"),而不是memcpy.

Also, by definition, sizeof(char) == 1 in C, so 6*sizeof(char)is redundant

此外,根据定义,C 中的 sizeof(char) == 1,因此6*sizeof(char)是多余的

回答by Uri

C strings are null terminated (there's a \0 character at the end), that's how C knows when to stop printing or dealing with the buffer as a string . It is your responsibility to never put a string in a longer space than what you have allocated.

C 字符串以空字符结尾(末尾有一个 \0 字符),这就是 C 知道何时停止打印或将缓冲区作为 string 处理的方式。您有责任永远不要将字符串放在比您分配的空间更长的空间中。

Note that Hello\n is not a six character string, it is actually a seven character string. You use five for the Hello, one for the newline, and one for the null terminator.

请注意,Hello\n 不是一个六个字符的字符串,它实际上是一个七个字符的字符串。您使用五个作为 Hello,一个作为换行符,一个作为空终止符。

Trying to fit 7 characters into a six character buffer is considered a bug, I am not sure if it is responsible for the problems you are currently having, but it seems like the copying of 6 characters would not copy the null terminator. So I would actually expect your print to go beyond the Hello and into some actual junk.

尝试将 7 个字符放入 6 个字符的缓冲区被认为是一个错误,我不确定它是否对您当前遇到的问题负责,但似乎复制 6 个字符不会复制空终止符。所以我实际上希望你的印刷品超越 Hello 并变成一些实际的垃圾。

回答by Sanjay Manohar

when it reaches a zero. you need 7 chars.

当它达到零时。你需要7个字符。