Узнав, что оба значения strncmp
- это не то, что кажется, и что strlcpy
недоступно в моей операционной системе (Linux), я решил, что могу попробовать написать сам.
Я нашел цитату из Ульриха Дреппера, сопровождающего libc, который опубликовал альтернативу strlcpy
, используя mempcpy
. У меня тоже нет mempcpy
, но его поведение было легко воспроизвести. Во-первых, это тестовый пример у меня
#include <stdio.h>
#include <string.h>
#define BSIZE 10
void insp(const char* s, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%c ", s[i]);
printf("\n");
for (i = 0; i < n; i++)
printf("%02X ", s[i]);
printf("\n");
return;
}
int copy_string(char *dest, const char *src, int n)
{
int r = strlen(memcpy(dest, src, n-1));
dest[r] = 0;
return r;
}
int main()
{
char b[BSIZE];
memset(b, 0, BSIZE);
printf("Buffer size is %d", BSIZE);
insp(b, BSIZE);
printf("\nFirst copy:\n");
copy_string(b, "First", BSIZE);
insp(b, BSIZE);
printf("b = '%s'\n", b);
printf("\nSecond copy:\n");
copy_string(b, "Second", BSIZE);
insp(b, BSIZE);
printf("b = '%s'\n", b);
return 0;
}
И вот его результат:
Buffer size is 10
00 00 00 00 00 00 00 00 00 00
First copy:
F i r s t b =
46 69 72 73 74 00 62 20 3D 00
b = 'First'
Second copy:
S e c o n d
53 65 63 6F 6E 64 00 00 01 00
b = 'Second'
Вы можете видеть во внутреннем представлении (созданные строки insp()
), что есть некоторый смешанный шум, например строка формата printf()
в проверке после первой копии, и посторонний 0x01 во второй копии.
Строки скопированы без изменений, и он корректно обрабатывает слишком длинные исходные строки (давайте пока проигнорируем возможную проблему с передачей 0 в качестве длины copy_string
, я исправлю это позже).
Но почему в моем месте назначения находится содержимое внешнего массива (из строки формата)? Это как если бы пункт назначения был действительно ИЗМЕНЕН в соответствии с новой длиной.