only-lucky 2024-06-08 23:19 采纳率: 50%
浏览 3
已结题

Linux环境C未结谜团

本代码是在linux下gcc版本为9.4环境编写。请看代码。


```c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glob.h>


int main(int argc,char *argv[])
{
     char temp[] = "hello";    
    char buf[5];

    printf("sizeof buf = %ld \n",sizeof(buf ));
    printf("%s \n",buf);
    
    strncpy(buf,"\0",sizeof(buf));


    strncpy(buf,"hello",sizeof(buf));

   

    printf("%s \n",buf);

    return 0;
}

大家请大胆的猜一下buf会输出什么内容? hell对把,实际结果请看以下截图。

img

惊不惊喜?意不意外?
但是要是把 char temp[] = "hello" 注释掉的话就显示正常。有人知道这是什么原因么

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-08 23:19
    关注

    引自免费微信小程序:皆我百晓生

    在您提供的代码中,strncpy() 函数的行为看起来不符合预期,这可能是因为您对 strncpy() 的理解有误。strncpy() 是一个用于复制字符串的函数,它有一个重要的特性:如果目标缓冲区的空间不足,它不会添加终止符(\0),除非恰好在指定的字符数内完成了复制。

    在这个例子中,您首先尝试将空字节序列 \0 复制到 buf 中,然后尝试复制 "hello" 到同一个缓冲区。由于 buf 只有 5 个字节,当第一次调用 strncpy(buf, "\0", sizeof(buf)); 时,实际上只复制了第一个空字节到 buf 中。然后,第二次调用 strncpy(buf, "hello", sizeof(buf)); 时,因为前一个空字节已经占据了 buf 的第一个位置,所以 "hello" 的五个字符被写入到剩余的四个位置上,并且没有添加终止符,因此输出的结果是相连的两个 "hello" 字符串。

    要解决这个问题,您可以考虑在两次调用之间手动添加终止符,确保每次操作后 buf 都是一个有效的 C 字符串。以下是修改后的代码:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <glob.h>
    
    int main(int argc, char *argv[]) {
        char temp[] = "hello";
        char buf[5];
    
        printf("sizeof buf = %zu \n", sizeof(buf));
        printf("%s \n", buf);
    
        // Add null terminator after the first call to strncpy()
        buf[sizeof(buf) - 1] = '\0';
    
        strncpy(buf, "\0", sizeof(buf) - 1);  // Don't copy terminating null byte
    
        // Add null terminator again after the second call to strncpy()
        buf[sizeof(buf) - 1] = '\0';
    
        strncpy(buf, "hello", sizeof(buf) - 1);  // Don't copy terminating null byte
    
        printf("%s \n", buf);
    
        return 0;
    }
    

    这里我使用 %zu 替换了 %ld 来匹配 sizeof(buf) 返回值类型为 size_t。同时,我确保每次 strncpy() 调用之后,都在 buf 的末尾手动添加终止符。这样,即使在第一次复制空字节序列后,buf 仍然会被正确地视为一个有效的 C 字符串,从而在第二次复制 "hello" 后得到期望的输出。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 6月30日
  • 已采纳回答 6月22日
  • 创建了问题 6月8日