如何在C中输入变量字符/字符串?

时间:2015-08-20 17:36:32

标签: c

我有一个问题,我需要从用户(命令行)获取输入,它将采用[char char char]或[char string]格式,即3个字符或char和字符串。

我需要自己的字符和字符串,没有空格等,所有这些都必须在一行输入。

我目前的解决方案仅适用于3个字符,但我不确定如何使它适用于3个字符或字符串和字符串。

这是我目前的代码:

char move[3];

while(1){
    int i = scanf(" %c %c %c", &move[0], &move[1], &move[2]);

    if(i == 3){
        break;
    }
}       

如果有人知道我如何能达到我的目标,我将非常感激。

2 个答案:

答案 0 :(得分:2)

一种常见的方法是使用这样的东西:

> db.setLogLevel(-1, "query")

然后使用C字符串处理函数解析move。您可以使用strtok获取2+令牌。如果每个元素都有strlen 1那么这就是你的3个字符的情况,如果第一个字符是strlen 1而第二个是1+长度则是你的第二个案例。

答案 1 :(得分:-1)

您可以使用状态机来分析和解析您的输入。您可以在读取输入时定义可以在任何点处的某些状态,以及基于输入的状态之间的转换。例如:

  • expect_move1 - 你还没有读过任何输入,你期望看到一个非空白字符后跟空格;
  • expect_move2_or_string - 您已经阅读了第一步,您希望看到的下一件事是另一个单字符后跟空白*或*一系列非空白字符其次是空白;
  • expect_move3 - 您已经读过第二个单个非空白字符,后面跟着空格,接下来你要看的是第三个单个非空白字符,后跟空格;
  • 已完成 - 您已阅读3个单个非空白字符*或*您已阅读1个单个非空白字符,后跟一系列非空白字符,以及唯一应该留下的是空白;
  • 错误 - 您阅读了一些您没想到的内容,并且输入格式不正确。

我编写了一些快速实现的实现,它按如下方式处理各种输入:

[fbgo448@n9dvap997]~/prototypes/state: ./state
a
..^
Bad input found at position 3
a b
....^
Bad input found at position 5
a b c
Read moves: a b c
a b c d
......^
Bad input found at position 7
a string
Read move: a string
a string c
.........^
Bad input found at position 10
a stringthatstoolongforourstringbuffer
......................^
Bad input found at position 23
some string
.^
Bad input found at position 2
a string followed by some junk
.........^
Bad input found at position 10

出于您的目的,这可能是过度杀伤的定义,并且比您需要的更多参与;考虑一个写得不好的例子,说明你可能希望将来处理这样的事情:

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

/**
 *   State            Input                   New State
 *   -----            -----                   ---------
 *   exp_mv1          char + whitespace       exp_mv2_or_str
 *   exp_mv2_or_str   char + whitespace       exp_mv3
 *   exp_mv2_or_str   char seq + whitespace   done
 *   done             whitespace              done
 *
 *  Inputs that do not match the above lead to the error state.
 *
 */
int getInput( const char *input,     // input string
              size_t inputSize,      // length of input string
              char *moves,           // array to store moves
              size_t movesLen,       // length of moves array
              char *str,             // array to store string element
              size_t strLen,         // max length of string element array
              size_t *movesRead,     // number of moves read so far
              int *count)            // number of characters processed
{
  enum state { exp_mv1,              // expect a single char + whitespace
               exp_mv2_or_str,       // expect char + whitespace or string
               exp_mv3,              // expect char + whitespace
               done,                 // expect only whitespace until newline
               error }               // found something unexpected
    curState = exp_mv1;              // start in exp_mv1
  *count = 0;

  while ( *count < inputSize &&       // process input while we are not 
           curState != error &&       // at the end of the string and
           input[*count] &&           // we aren't in the error state
           input[*count] != '\n' )
  {
    switch( curState )
    {
      case exp_mv1:
        if ( !isspace( input[*count] ) )        // non-whitespace
        {
          if ( isspace( input[++(*count)] ) )   // followed by whitespace
          {
            moves[0] = input[((*count)++)-1];   // save the move
            (*movesRead)++;                     // update moves counter
            curState = exp_mv2_or_str;          // go to new state
          }
          else
          {
            curState = error;                   // bad input
          }
        }
        else
          (*count)++;                           // read whitespace, move
        break;                                  // to next character

      case exp_mv2_or_str:
        if ( !isspace( input[*count] ) )        // non-whitespace character
        {
          if ( isspace( input[++(*count)] ) )   // followed by whitespace
          {
            moves[1] = input[((*count)++)-1];   // save the move
            (*movesRead)++;                     // update moves counter
            curState = exp_mv3;                 // go to new state
          }
          else
          {
            size_t i = 0;                       // non-whitespace
            --(*count);                         // back up one character
            while ( i < strLen &&               // read characters until we
                    !isspace( input[*count] ) ) // run out of space or hit
            {                                   // a whitespace character
              str[i++] = input[(*count)++];     // and save to str
            }
            str[i] = 0;                         // 0-terminate str 

            if ( isspace( input[*count] ) )     // if current character is
              curState = done;                  // not whitespace, then the
            else                                // string was longer than
            {                                   // what we can store
              (*count)--;                       // previous character was first bad character
              curState = error;                 // go to error state
            }
          }
        }
        else
          (*count)++;                           // skip over whitespace character
        break;

      case exp_mv3:
        if ( !isspace( input[*count] ) )        // non-whitespace
        {
          if ( isspace( input[++(*count)] ) )   // followed by whitespace
          {
            moves[2] = input[((*count)++)-1];   // save the move
            (*movesRead)++;                     // update the moves counter
            curState = done;                    // go do done state
          }
          else
          {
            --count;                            // non-whitespace, previous char is bad character
            curState = error;                   // go to error state         
          }
        }
        else
          (*count)++;                           // skip whitespace character
        break;

      case done:
        if ( !isspace( input[*count] ) )        // non-whitespace character
        {
          curState = error;                     // go to error state
        }
        else
          (*count)++;                           // skip whitespace character

        break;

      case error:                               // no processing,
        break;
    }
  }
  return curState == done;
}

int main( void )
{
   char input[81];
   char moves[3];
   char str[21];
   size_t movesRead;
   int charsRead;

   while( fgets( input, sizeof input, stdin ) )
   {
     movesRead = 0;
     if ( getInput( input, strlen( input ), moves, sizeof moves, str, sizeof str, &movesRead, &charsRead ) )
     {
       if ( movesRead == 3 )
         printf( "Read moves: %c %c %c\n", moves[0], moves[1], moves[2] );
       else
         printf( "Read move: %c %s\n", moves[0], str );
     }
     else
     {
       const char *leader = ".....................................................................";

       fprintf( stderr, "%*.*s^\n", charsRead, charsRead, leader );
       fprintf( stderr, "Bad input found at position %d\n", charsRead+1 );
     }
  }

  return 0;
}

我为发表一部小说而道歉 - 你在一个奇怪的时刻抓住了我。