Usage of fgets function in C

后端 未结 7 1605
野性不改
野性不改 2020-12-19 17:51

One of my assignments in to write my own UNIX Shell. To receive input from the user, I am using fgets to capture the input as a string but I\'m not really sure how it works.

相关标签:
7条回答
  • 2020-12-19 18:22

    Probably the easiest way to handle this is to switch to using scanf to read the input:

    char command[51];
    
    scanf("%50[^\n]", command);
    
    if (0 == strcmp(command, "exit"))
        do_something();
    
    0 讨论(0)
  • 2020-12-19 18:22

    As noted, fgets(3) gives you the trailing '\n'. If you use gets(3), you don't gets the trailing newline. Nothing like consistency, sez I.

    Perl has a hand chomp() function that trims the trailing newline if its present — you could do worse than to roll your own:

    #define NUL ((char)0)
    void chomp( char *s )
    {
      if ( s != null )
      {
        int len = strlen(s) ;
        if ( len >= 1 && s[len-1] == "\n" )
        {
          s[len-1] = NUL ;
        }
      }
      return ;
    }
    
    0 讨论(0)
  • 2020-12-19 18:24

    fgets considers the line terminator as a valid character. That's the extra character you are receiving.

    Just do something like command[strlen(command) - 1] = '\0'; to remove the line terminator. Then you are free to do all your strcmp's.

    0 讨论(0)
  • 2020-12-19 18:29

    From the fgets manual page:

    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.

    Bottom-line: you have an extra newline at the end of your string when comparing.

    0 讨论(0)
  • 2020-12-19 18:33

    fgets is capturing the line break, too.

    Note that you can overcome this in a few ways, one might be using strncmp:

    if((strncmp(command, "exit", 4)) == 0)
    

    which checks if only the first 4 characters of command match (though this might not be the right option for you here).

    Another tactic is to check with the line break in place:

    if((strcmp(command, "exit\n")) == 0)
    
    0 讨论(0)
  • 2020-12-19 18:35

    fgets will always include the line termination character in the input string. You can remove any space, including the newline characters, from the end of your "command" by doing:

    char command[50];
    fgets(command, sizeof(command), stdin);
    
    size_t length = strlen(command);
    // Trim off trailing "spaces" including newline characters
    while ((length > 0) && isspace(command[length-1]))
          command[--length] = '\0';
    
    printf("Your Command: %s\n", &command); // Include newline now...
    // This is computed above...
    // int length = strlen(command);
    
    // Continue as before
    
    0 讨论(0)
提交回复
热议问题