Dan Brenner
Dan Brenner

Reputation: 888

Can't determine value of character at the end of a string

I'm new to C programming. I am trying to make a program that takes some simple input. However I found that on comparison of my input string to what the user "meant" to input, there is an additional character at the end. I thought this might be a '\0' or a '\r' but that seems not to be the case. This is my snippet of code:

char* getUserInput(char* command, char $MYPATH[])
{
    printf("myshell$ ");
    fgets(command, 200, stdin);
    printf("%u\n", (unsigned)strlen(command));

    if ((command[(unsigned)strlen(command) - 1] == '\0') || (command[(unsigned)strlen(command) - 1] == '\r'))
    {
        printf("bye\n");
    }

return command;
}

The code shows that when entering, say "exit" that 5 characters are entered. However I can't seem to figure out the identity of this last one. "Bye" never prints. Does anyone know what this mystery character could be?

Upvotes: 2

Views: 165

Answers (3)

alk
alk

Reputation: 70893

The magical 5th element most probably is a newline character: \n

From man fgets() (emphasis by me):

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.

To prove this print out each character read by doing so:

char* getUserInput(char* command, char $MYPATH[])
{ 
  printf("myshell$ ");
  fgets(command, 200, stdin);
  printf("%u\n", (unsigned)strlen(command));

  {
    size_t i = 0, len = strlen(command);
    for (;i < len; ++i)
    {
      fprintf(stderr, "command[%zu]='%c' (%hhd or 0x%hhx)\n", i, command[i], command[i], command[i]); 
    }
  }

  ...

Upvotes: 9

Zac Wrangler
Zac Wrangler

Reputation: 1445

The reason you don't see the last char is because strlen() won't calculate '\0' into the string's length. So testing for '\0' wont succeed. for instance, const char* a = "abc"; then strlen(a) will be 3. if you want to test it, you need to access it by command[strlen(command)]

The reason for getting strlen equals to 5 on "exit" is because fgets will append the '\n' character at the end of the input. You could test it by command[strlen(command) -1 ] == '\n'

Upvotes: 0

Iłya Bursov
Iłya Bursov

Reputation: 24146

assumptions

  1. array indexes in c are started with 0
  2. strlen returns length of string

so, if you have string "exit", this will be 5 symbols in array = e, x, i, t, \0, strlen return 4, but you're trying to decrement it by 1, so you're checking last symbol in string, instead on NULL terminator

to check NULL terminator use command[strlen(command)] - this will give you \0 always, so there is no sense in it

if you want to compare strings use strcmp function

UPDATE: issue with your program is because fgets appends \n symbol at then end of string:

A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.

Upvotes: 2

Related Questions