当 dest 小于 src 但又足够大以容纳 src 所需的子字符串时,为什么 strncpy() 会产生垃圾?

Cod*_*der 2 c string strcpy strncpy

我尝试使用strncpy()限制复制到 dest (此处为str1 )的 n 字节数。\ndest 对于 n 字节来说足够大,但是当 dest 小于源时(此处为argv[1 ])。\n当我使 dest 足够大以容纳源时,这看起来有所不同。

\n

这是代码:

\n
#include <stdio.h>                                                              \n#include <string.h>                                                             \n                                                                                \nint main(int argc, char *argv[])                                                \n{                                                                               \n/* // Works when str1[?] is 20:                                                                    \n  char str1[20];                                                                \n  char str2[20]; */                                                             \n                                                                                \n  // produces garbage, str1 is smaller than argv[1] but big enough for the 4 bytes copied                                                            \n  char str1[10];                                                                \n  char str2[10];                                                                \n                                                                                \n  printf("argc = %i\\n", argc);                                                  \n  if (argc <= 1 || argc > 2){                                                   \n    printf("Input Example:\\n"                                                   \n           "  %s SEGMENT:OFFSET\\n"                                              \n           "  %s 0100:F00A\\n", argv[0], argv[0]);                               \n    return 0;                                                                   \n  }                                                                             \n  printf("strlen(argv[1]) = %li, argv[1] = %s\\n"                                \n          , strlen(argv[1]), argv[1]);                                          \n                                                                                \n  // str1                                                                       \n  strncpy(str1, argv[1], 4); // copying 4 bytes to str1                                                   \n  printf("Copy only 4 Bytes -> sizeof(str1) = %li, "                            \n         "strlen(str1) = %li, str1 = %s\\n", sizeof(str1), strlen(str1), str1);  \n                                                                                \n  // str2                                                                       \n  strncpy(str2, argv[1], 3); // copying 3 bytes to str2                                                   \n  printf("Copy only 3 Bytes -> sizeof(str2) = %li, "                            \n         "strlen(str2) = %li, str2 = %s\\n", sizeof(str2), strlen(str2), str2);  \n                                                                                \n  return 0;                                                                     \n}                      \n
Run Code Online (Sandbox Code Playgroud)\n

0100:F00A 的输入产生:

\n
./test.bin 0100:F00A\nargc = 2\nstrlen(argv[1]) = 9, argv[1] = 0100:F00A\nCopy only 4 Bytes -> sizeof(str1) = 10, strlen(str1) = 8, str1 = 0100\xef\xbf\xbdU\nCopy only 3 Bytes -> sizeof(str2) = 10, strlen(str2) = 3, str2 = 010\n\n
Run Code Online (Sandbox Code Playgroud)\n

预期只是str1 = 0100

\n

我也确实想知道为什么str2是正确的,它的初始数组大小与str1一样小。

\n

当我改变时

\n
./test.bin 0100:F00A\nargc = 2\nstrlen(argv[1]) = 9, argv[1] = 0100:F00A\nCopy only 4 Bytes -> sizeof(str1) = 10, strlen(str1) = 8, str1 = 0100\xef\xbf\xbdU\nCopy only 3 Bytes -> sizeof(str2) = 10, strlen(str2) = 3, str2 = 010\n\n
Run Code Online (Sandbox Code Playgroud)\n

\n
char str1[10] \n
Run Code Online (Sandbox Code Playgroud)\n

并通过这样做使其大于 argv[1] 的输入,则输出是正确的:

\n
./test.bin 0100:F00A\nargc = 2\nstrlen(argv[1]) = 9, argv[1] = 0100:F00A\nCopy only 4 Bytes -> sizeof(str1) = 20, strlen(str1) = 4, str1 = 0100\nCopy only 3 Bytes -> sizeof(str2) = 20, strlen(str2) = 3, str2 = 010\n
Run Code Online (Sandbox Code Playgroud)\n

看起来 strncpy 首先将所有内容复制到 dest,然后删除后面的其余部分。但这是 strncpy 的工作方式吗?\n我假设它只是复制所需的内容,即 4 个字节。

\n