读取包含命令选项和参数的输入,用C中的空格分隔

时间:2017-08-24 11:07:50

标签: c input dynamic switch-statement scanf

我有用户输入,由3个或更少的参数组成,用空格分隔,例如

A Name 20

第一个论点' A' (在这种情况下为Add)表示一个命令选项,它确定如何处理输入的其余部分。在这种情况下,第二个参数是要添加到struct元素的链接列表的名称,最后一个是要存储在同一struct元素上的int类型值。

其他命令选项包括例如' P'用于打印列表中的所有元素和' D Name',它从列表中删除具有给定名称的元素。

到目前为止,我有以下代码,但它似乎不能很好地工作。我只包含了addElem函数,因为这件事似乎有些不对劲。我不确切知道我的代码出了什么问题。当我尝试通过例如添加元素时'名称20',我得到多行'无效命令',并且列表中似乎找不到该元素。交换机循环不是一个完全处理这个问题的好方法,还是我在这里做了其他非常错误的事情?

typedef struct element {
   char *name;
   int val;
   struct element *next;
} Elem;

/* Read name dynamically */
char *readName()
{
   int ch, i = 0;
   char *name = malloc(1);

   name[0] = '\0';
   do {
      ch = getchar();
      name = realloc(name, (i + 2));
      name[i] = (char) ch;
      name[i+1] = '\0';
      i++;
   } while (ch != ' ' && ch != '\n');

   return name;
}

/* Add element "name" into linked list */
Elem *addElem(Elem *first)
{
   /* Create new element */
   Elem *new_elem = malloc(sizeof(Elem));

   new_elem->name = readName();
   scanf(" %d", &new_elem->val);
   new_elem->next = NULL;

   /* Add new element to linked list */
   if (first == NULL)
      first = new_elem;
   else {
      Elem *ptr = first;
      while (ptr->next != NULL)
         ptr = ptr->next;
      ptr->next = new_elem;
   }

   return first;
}

int main()
{
   char cmd;
   Elem *first = malloc(sizeof(Elem));

   while (1) {
      scanf("%c", &cmd);
      switch (cmd) {
         case 'A':
            first = addElem(first);
            break;
         case 'D':
            first = delElement(first);
            break;
         case 'P':
            printElems(first);
            break;
         default:
            printf("Invalid command\n");
            break;
      }
   }

   return 0;
}

1 个答案:

答案 0 :(得分:0)

您的代码首先读取的是" A"。然后它读取名称直到下一个空格...由于A之后有一个空格,意味着它在读取一个字符后停止。然后它尝试读取一个数字,这个数字还没有,因此我们仍然在第二个字段的开头处。

到目前为止,您已经阅读过" A"现在你又回到了代码的开头,这就是为什么你得到了大量的"无效命令"消息。

如果你将整行读入一个字符串并将其作为一个命令处理而不是逐点读取,那么你会好多了。这是一个如何做到这一点的简单例子。

char cmdline[1024],*pos;
int num;
char name[50], *namepos;

if(fgets(cmdline,1024,stdin))
  {
  switch(*cmdline)
    {
  case 'A':
    pos=cmdline+1;
    while(isspace(*pos)) pos++;
    namepos=name;
    while((*pos)&&(!isspace(*pos)))
      {
      *namepos=*pos;
      namepos++;
      pos++;
      }
    *namepos='\0';
    if(sscanf(pos," %d",&num)==1)
      {
      // Do stuff now that you've processed the line
      }
  break;
    }
  }