strlen не возвращает правильное количество символов - PullRequest
0 голосов
/ 21 января 2019

По какой-то причине, когда я ввожу /bin/echo с последующим вводом, strlen здесь говорит 14, когда должно быть 10. Я не могу понять, почему.

char buffer[BUF_SIZE];   // BUF_SIZE = 100
ssize_t readIn = read(STDIN_FILENO, &buffer, BUF_SIZE);

printf("strlen=%lu\n", strlen(buffer));

Это как-то связано с / символом ??

EDIT:

Вот что выводит буфер, когда я перебираю по одному символу за раз:

#0: c=/ / hex=2f
#1: c=b / hex=62
#2: c=i / hex=69
#3: c=n / hex=6e
#4: c=/ / hex=2f
#5: c=e / hex=65
#6: c=c / hex=63
#7: c=h / hex=68
#8: c=o / hex=6f
#9: c=
 / hex=a
#10: c= / hex=5
#11: c=? / hex=ffffff90
#12: c=? / hex=ffffffff
#13: c= / hex=7f

Ответы [ 2 ]

0 голосов
/ 21 января 2019

strlen() - для определения длины строки .В C A string имеет нулевой символ в конце, иначе это не строка.Если считываемые данные не содержат нулевой символ, это не строка.

Вместо этого используйте возвращаемое значение из read(), чтобы определить длину считывания.Чтобы напечатать ssize_t, приведенный к широкому типу, например long long или intmax_t (лучше), так как ssize_t не имеет указанного спецификатора печати. ​​ 1 2

Примечание: удалите & из буфера, так как он не нужен.

char buffer[BUF_SIZE];   // BUF_SIZE = 100
// ssize_t readIn = read(STDIN_FILENO, &buffer, BUF_SIZE);
ssize_t readIn = read(STDIN_FILENO, buffer, BUF_SIZE);

// printf("strlen=%lu\n", strlen(buffer));
printf("length = %lld\n", (long long) readIn);
// or
printf("length = %jd\n", (intmax_t) readIn);

1 Руководство программиста Linux делаетимеют «z: следующее целочисленное преобразование соответствует аргументу size_t или ssize_t», поэтому в коде можно использовать printf("length = %zd\n", readIn);

2 POSIX допускает либо более широкий тип, либо аналог со знаком size_t.

0 голосов
/ 21 января 2019

Проблема в том, что read не помещает нулевой терминатор в buffer. Если вы запустите свою программу с valgrind, вы почти наверняка увидите ошибки о недопустимом чтении, поскольку buffer неинициализирован.

У вас есть несколько вариантов:

  • Не используйте read, но то, что автоматически добавит нулевой терминатор.
  • Используйте read, но добавьте нулевой терминатор вручную. buffer[readIn] = '\0' - наивное решение (отсутствует проверка ошибок и границ).
  • Инициализировать buffer только нулевыми терминаторами. Это не сработает, если ваш ввод больше BUF_SIZE, поэтому будьте осторожны.
...