Alexander Nenartovich
Alexander Nenartovich

Reputation: 826

Trimming a trailing \0 from fgets() in C

I am writing a simple shell program in C where the program accepts commands from user in the command line, tokenizes the input into the array and then uses execvp() function to execute user commands. To read the user input I am using fgets() function:

char command[MAX];
fgets(command, MAX, stdin);

Now here where's my problem is (and I am very new to C programming). If the user types, for example, ls -af and I check the length of the typed string like

strlen(command)

the result is 7 even though there are only 6 characters typed. I understand that this is because fgets() always adds a \0 at the end of a string. This, however, causes problems for my program later. I tokenize the input using strtok() function like so:

char* token;
int i = 0;
char* args[10];
token = strtok(command, " ");
while(token != NULL)
  {   
      args[index] = token;
      token = strtok(NULL, " ");
      index ++ ;
   }
  args[index] = NULL;

After this, the last element in the args array before NULL (-af in this case) retains that trailing \0 produced by fgets(). This, in turn, causes a problem for my execvp() call since it does not recognize the last element in the array. I assume it reads it as -af\0 whereas it should be just -af. Is there a way to trim that last \0 produced by fgets() function or is there an easier way to read an input from the user? Thank you in advance!

Upvotes: 2

Views: 368

Answers (1)

Addison
Addison

Reputation: 8357

As stated in the comments above, you're probably seeing the newline being stored in the string.

Reading the MAN (3) page for fgets (emphasis mine):

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 terminating null byte ('\0') is stored after the last character in the buffer.

If you want to strip newlines, you can see this post which has an answer suggesting that you use something like this:

buffer[strcspn(buffer, "\n")] = 0;

Upvotes: 2

Related Questions