doctopus
doctopus

Reputation: 5647

strlen not returning correct number of characters

For some reason when I input /bin/echo followed by enter, strlen here says 14 when it should be 10. I can't seem to figure out why.

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

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

Is it something to do with / character??

EDIT:

This is what buffer prints out when I loop through one char at a time:

#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

Upvotes: 0

Views: 426

Answers (2)

chux
chux

Reputation: 153338

strlen() is for determining the length of a string. In C, A string has a null character at the end,else it is not a string. Unless the data read includes a null character, it is not a string.

Instead, use the return value from read() to determine the length read. To print a ssize_t, cast to a wide type, such as long long or intmax_t (better), as ssize_t lacks a specified print specifier.1 2

Note: drop the & from buffer as it is not needed.

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 Programmer's Manual does have "z: A following integer conversion corresponds to a size_t or ssize_t argument", so there code can use printf("length = %zd\n", readIn);

2 POSIX allows either a wider type or the signed analog of size_t.

Upvotes: 7

Stephen Newell
Stephen Newell

Reputation: 7828

The issue is that read doesn't put the null terminator in buffer. If you run your program with valgrind, you'll almost certainly see errors about an invalid read since buffer is uninitialized.

You have a few options:

  • Don't use read, but something that will add the null terminator automatically.
  • Use read, but add the null terminator manually. buffer[readIn] = '\0' is a naive solution (missing error and bounds checking).
  • Initialize buffer to nothing but null terminators. This won't work if your input is larger than BUF_SIZE, so be careful.

Upvotes: 4

Related Questions