【问题标题】:Why does copying a specific buffer size with memcpy and sprintf, prints more chars in new buffer than there are in the original buffer?为什么使用 memcpy 和 sprintf 复制特定的缓冲区大小,在新缓冲区中打印的字符比原始缓冲区中的字符多?
【发布时间】:2021-12-06 19:46:48
【问题描述】:

我有一个一般性的理解问题!这是我的代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>

int main() {
    // read user input
    char input[64] = {0};
    read(0, input, 64);
    printf("You've entered ");
    printf(input);

    char newbuf[128];
    char smallbuf[8];

    // copy into smallbuf 8 bytes of input
    memcpy(smallbuf, input, 8);

    // send smallbuf of 8 bytes as string into newbuf
    sprintf(newbuf, "%s", smallbuf);

    // print newbuf
    printf(&newbuf[0]);

    return 0;
}

我得到 7 个字符的行为还可以,它确实打印了 7 个字符:

$ gcc a.cpp -o a.out && ./a.out
1234567
You've entered 1234567
1234567
1234567

但是使用 8 个字符,它会打印出更多的字符,我想知道为什么会这样:

$ gcc a.cpp -o a.out && ./a.out 
12345678
You've entered 12345678
1234567812345678

谢谢你解释我! :)

【问题讨论】:

  • 字符串有 null 来标记结束。如果您不复制 null,则字符串不会终止
  • @stark 这是否意味着如果我们写入 n-1 个字符作为输入,那么当我们点击输入终止时,null 字符被复制,但是当我们准确写入 n 个字符时,其中 n 是字节的大小复制然后我们省略终止空字符,因为我们用输入的最后一个字符覆盖它?
  • 调用read时没有终止空字符。你已经通过用全 0 初始化你的 input 数组来绕过这个问题,但是当你写信给 smallbufnewbuf 时,问题就出现了。
  • 另外,请不要写printf(&amp;newbuf[0])之类的东西。如果用户碰巧键入了一个包含一个或两个% 符号的字符串,就会发生疯狂的事情!始终使用printf("%s", &amp;newbuf[0])puts(&amp;newbuf[0]) 打印字符串。 (在这种情况下,您可以使用printf("%s", newbuf)puts(newbuf)。)
  • memcpy 不知道字符串。看看 string.h 函数。

标签: c buffer


【解决方案1】:

代码试图打印一个字符数组,就好像它是一个导致未定义行为字符串smallbuf[] 肯定不包含 null 字符,因此它不是 字符串
"%s" 需要一个指向 字符串的匹配指针em>。

空字符

char smallbuf[8+1];
memcpy(smallbuf, input, 8);
smallbuf[8] = '\0';
printf("%s", smallbuf);

或以精度限制输出。打印最多 N 个字符或 null 字符的字符数组。

char smallbuf[8];
memcpy(smallbuf, input, 8);
printf("%.8s", smallbuf);

类似问题适用于printf(input);


不要编码printf(input);,因为当input[] 包含% 时,这可能会导致未定义的行为

// printf(input);
printf("%s", input);

更好的代码会检查read(0, input, 64) 的返回值。

【讨论】:

    猜你喜欢
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    相关资源
    最近更新 更多