fgets is getting skipped

孤者浪人 提交于 2019-12-04 05:25:48

问题


I have little program where I want to ask for an option and then for a filename.

  //Some code before
   printf("######################\n");
   printf("# 1. Register a file #\n");
   printf("# 2. Get global list #\n");
   printf("# 3. Download a file #\n");
   printf("# 4. Quit / Exit     #\n");
   printf("######################\n");
   printf("Enter decision: ");
      fflush(stdin);
   action = getchar();
   action -= '0';
   sprintf(input, "[%d]--", action);
   switch (action)
   {
    case 1:
     printf("Enter file name: ");
        fflush(stdin);
     fgets(input+strlen(input), LINE_LEN, stdin);
     input[strlen(input)] = (input[strlen(input)] == '\n') ? 0 : input[strlen(input)];
     if(write(sock, input, sizeof(input)) == -1) perror("Clienthandler Write 3");
    break;
//some code after

The problem is that my fgets is getting skipped, even in gdb, gdb shows after the fgets for inspect input the value "\n\000]--" when action = 1

This is the console output:

######################
# 1. Register a file #
# 2. Get global list #
# 3. Download a file #
# 4. Quit / Exit     #
######################
Enter decision: 1
Enter file name: ######################
# 1. Register a file #
# 2. Get global list #
# 3. Download a file #
# 4. Quit / Exit     #
######################
Enter decision: ^C

回答1:


fget() is not getting skipped but reads the left over new-line from the previous input using getchar().

It is all about complete error checking and sane logging:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


#define LINE_LEN (1024)


int main(void)
{
  int action = 0;
  char input[LINE_LEN] = {0};
  size_t len = 0;

  printf("enter decision: ");
  {
    int c = fgetc(stdin); /* equivalent to getchar() */
    if (EOF == c)
    {
      putc('\n');

      if (ferror(stdin))
      {
        perror("fgetc(stdin) failed");
      }
      else
      {
        fprintf(stderr, "read EOF, aborting ...\n");
      }

      exit(EXIT_FAILURE);
    }

    action = c;
  }

  /* read left over from previous input: */
  {
    int c = fgetc(stdin);
    if (EOF == c)
    {
      putc('\n');

      if (ferror(stdin))
      {
        perror("fgetc(stdin) failed");
        exit(EXIT_FAILURE);
      }
    }
    else if ('\n' != c)
    {
      fprintf(stderr, "read unexpected input (%d), aborting ...\n", c);
      exit(EXIT_FAILURE);
    }
  }

  len = strlen(input);
  if (LINE_LEN <= len + 1) 
  {
    fprintf(stderr, "input buffer full, aborting ...\n");
    exit(EXIT_FAILURE);
  }

  switch(action - '0')
  {
    case 1:
      printf("enter file name: ");
      if (NULL == fgets(input + len, LINE_LEN - len, stdin))
      {
        putc('\n');

        if (ferror(stdin))
        {
          perror("fgets() failed");
        }
        else
        {
          fprintf(stderr, "missing input, aborting ...\n");
        }

        exit(EXIT_FAILURE);
      }

      (input + len)[strcspn(input + len, "\n")] = '\0'; /* cut off new-line, if any. */

      printf("read file name '%s'\n", input + len);

      break;

    default:
      fprintf(stderr, "unknown action (%d), aborting ...\n", action);
      exit(EXIT_FAILURE);

      break;
  }
}


来源:https://stackoverflow.com/questions/49830399/fgets-is-getting-skipped

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!