简体   繁体   English

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

[英]Read input consisting a command option and arguments, separated by white spaces, in C

I have user input which consists of 3 or less arguments, separated by white spaces, such as 我的用户输入由3个或更少的参数组成,并用空格隔开,例如

A Name 20

The first argument 'A' (Add in this case) represents a command option, which determines what to do with the rest of the input. 第一个参数“ A”(在这种情况下为Add)代表命令选项,该选项确定如何处理其余输入。 Second argument in this case is the name to be added to a linked list of struct elements, and the last one is an int type value to be stored on the same struct element. 在这种情况下,第二个参数是要添加到结构元素的链接列表中的名称,最后一个参数是要存储在同一结构元素上的int类型值。

Other command options include eg 'P' for printing all the elements in the list and 'D Name', which deletes the element with the given name form the list. 其他命令选项包括例如用于打印列表中所有元素的“ P”和“ D名称”,后者从列表中删除具有给定名称的元素。

So far, I have the following code, but it does not seem to work very well. 到目前为止,我有以下代码,但它似乎不能很好地工作。 I only included the addElem function, since there seems to be something wrong with this whole thing. 我只包含了addElem函数,因为这整件事似乎有问题。 I don't know exactly what goes wrong with my code. 我不知道我的代码到底出了什么问题。 When I try to add an element by eg 'A Name 20', I get multiple lines of 'Invalid command', and the element does not seem to be found in the list. 当我尝试通过“名称20”添加元素时,出现多行“无效命令”,并且在列表中似乎找不到该元素。 Is the switch loop not a good way to handle this altogether or am I doing something else very wrong here? 开关循环不是解决此问题的好方法,还是我在这里做其他非常错误的事情?

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;
}

The first thing your code reads in is an "A". 您的代码读入的第一件事是“ A”。 Then it reads in the name up until the next space...which since there is a space after the A, means it stops that after reading just one character. 然后它会读取名称,直到下一个空格...由于A后面有一个空格,这意味着它仅读取一个字符就停止了该名称。 Then it tries reading in a number, which there isn't one as by this point we're at the beginning of the 2nd field still. 然后,它尝试读取一个数字,但没有一个数字,因为此时我们仍处于第二个字段的开头。

So far you've read in just "A " and now you're back to the beginning of the code again and that's why you get loads of "Invalid command" messages. 到目前为止,您只读了“ A”,现在又回到了代码的开头,这就是为什么您会加载“ Invalid command”消息的原因。

You'd be a whole lot better off if you read in the entire line into one string and process it as one command rather than reading in bits piecemeal. 如果您将整行读入一个字符串并将其作为一个命令处理,而不是零零碎碎地读起来,那么您的状况就会好得多。 Here is a simple example of how you might do that. 这是您可能如何执行此操作的简单示例。

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;
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM