2016-04-04 2 views
2

Мне нужно получить определенный ввод от пользователя (пользователю нужно ввести «init 3 4 NORTH», 3 - значение X (тип int), 4 - значение Y (тип int), NORTH - это значение направления (тип перечисления) init - это команда, которую они должны ввести.) Если пользователь просто вводит «3 4 СЕВЕР», программа ничего не сделает.C-получить конкретный ввод от пользователя

Я не могу использовать любое семейство scanf для ввода ввода.

Это то, что я реализовал до сих пор:

char input[10]; 
printf("Enter the command...\n"); 
if(fgets(input,sizeof(input),stdin)!= NULL){ 
    if(input[0]=='i' && input[1]=='n' && input[2]=='i' && input[3]=='t'){ 
     int x=atoi(&input[5]); 
     int y=atoi(&input[7]); 
     //doing similar things for Direction value..... 
     } 
    } 

так, что моя идея, чтобы проверить первое значение «INIT», и получить два Int значения, получим значение направления. Я надеюсь, что мои объяснения достаточно ясны, надеюсь, что кто-то может поделиться своими идеями.

+0

Во-первых, 'strncmp' http://man7.org/linux/man-pages/man3/strcmp.3.html поможет вам ... – Boiethios

+0

' sscanf' также поможет вам. –

+0

Вы не хотите использовать 'scanf', как насчет' sscanf'? – purplepsycho

ответ

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

int main(void) { 
    char input[256]; 
    printf("Enter the command...\n"); 
    if(fgets(input,sizeof(input),stdin) != NULL) { 
     char *tok; 
     if ((tok = strtok(input, " ")) != NULL) { 
      if (strcmp(tok, "init") != 0) 
       ;//error 
     } 
     else 
      ;//error 
     if ((tok = strtok(NULL, " ")) != NULL) { 
      /*Check first number and process it */ 
     } 
     else 
      ;//error 
     if ((tok = strtok(NULL, " ")) != NULL) { 
      /*Check second number and process it */ 
     } 
     else 
      ;//error 
     if ((tok = strtok(NULL, " \n")) != NULL) { 
      /*Check direction with strcmp */ 
     } 
     else 
      ;//error 
    } 
} 
+2

Это не будет соответствовать направлению, если вы не добавите 'новые строки' в разделители. 'strtok (NULL," \ n ")' –

+0

@WeatherVane, это правда, спасибо. – Boiethios

+0

@Morovaille это самый простой способ! –

2

Одна из проблем вашего подхода заключается в том, что он не будет работать, если цифры> 9. Если вы не хотите использовать scanf, вы можете прочитать строку с fgets, а затем использовать sscanf для извлечения его частей. Обратите внимание, что проверка показаний проверяется еще до того, как сами измерения будут проверены.

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

int main(void) { 
    char line[256]; 
    char cmd[32]; 
    char dir[32]; 
    int x; 
    int y; 

    if(fgets(line, sizeof line, stdin) == NULL) { 
     return 1; 
    } 
    if(sscanf(line, "%32s%d%d%32s", cmd, &x, &y , dir) != 4) { 
     return 1; 
    } 

    // now check you got valid command, values, and direction 
    if(strcmp(cmd, "init") != 0) { 
     return 1; 
    } 
    if(x < 0 || x > 99 || y < 0 || y > 99) { 
     return 1; 
    } 
    if(strcmp(dir, "NORTH") != 0) { 
     return 1; 
    } 

    printf("Your command: %s %d %d %s\n", cmd, x, y, dir); 
    return 0; 
} 
+0

Hah, программа предназначена только для консольной игры (9x9), поэтому я не нужно получить номер больше 9. Мне очень жаль, что я не могу использовать sscanf, мой преподаватель хочет, чтобы мы научились использовать fgets, так как они сказали, что это лучше, чем scanf и sscanf. Но ваш подход очень хорош в реальном мире программирования, спасибо за помощь! –

+2

@ Джейсон Ван, в этом случае ваш вопрос должен был сказать: «Мне не разрешено использовать« функции функции scanf », но вы сказали« это не безопасно ». Это использует 'fgets' и' sscanf' не 'scanf'. –

1

Поскольку вы не можете использовать scanf, вы должны проанализировать ввод вручную, довольно просто.

void getcommand() 
{ 
    /*Extra byte for null termination*/ 
    char input[BUFFER_SIZE+1]; 
    char keyword[BUFFER_SIZE+1]; 
    char command[BUFFER_SIZE+1]; 
    int x=0; 
    int y=0; 
    char direction[BUFFER_SIZE+1]; 
    printf("Enter the command...\n"); 
    if(fgets(input,sizeof(input),stdin)!= NULL){ 
     /*find the first space*/ 
     int index=0; 
     int i=0; 
     for(; index<BUFFER_SIZE; ++index){ 
      if(input[index]==' '){ 
       break; 
      } 
     } 
     /*Get the keyword*/ 
     for(; i<index; ++i){ 
      keyword[i]=input[i]; 
     } 
     /*set null termination*/ 
     keyword[index]=0; 
     /*Test valid keyword*/ 
     if(strcmp(keyword, "init")!=0){ 
      return; 
     } 
     /*save the command*/ 
     strcpy_s(command, sizeof(command),keyword); 
     /*skip the current space*/ 
     ++index; 
     ++i; 
     /*find the next space*/ 
     for(; index<BUFFER_SIZE; ++index){ 
      if(input[index]==' '){ 
       break; 
      } 
     } 
     /*Get the keyword*/ 
     int j=0; 
     for(; i<index; ++j, ++i){ 
      keyword[j]=input[i]; 
     } 
     /*add the null termination*/ 
     keyword[j]=0; 
     /*Get the coordinate*/ 
     int x=atoi(keyword); 
     /*skip the current space*/ 
     ++index; 
     ++i; 
     /*find the next space*/ 
     for(; index<BUFFER_SIZE; ++index){ 
      if(input[index]==' '){ 
       break; 
      } 
     } 
     /*Get the keyword*/ 
     for(j=0; i<index; ++j, ++i){ 
      keyword[j]=input[i]; 
     } 
     /*add the null termination*/ 
     keyword[j]=0; 
     int y=atoi(keyword); 
     /*skip the current space*/ 
     ++index; 
     ++i; 
     /*find the next space*/ 
     for(; index<BUFFER_SIZE; ++index){ 
      if(input[index]==' ' || input[index]=='\n'){ 
       break; 
      } 
     } 
     /*Get the keyword*/ 
     for(j=0; i<index; ++j, ++i){ 
      keyword[j]=input[i]; 
     } 
     /*add the null termination*/ 
     keyword[j]=0; 
     /*Test valid keyword*/ 
     if(strcmp(keyword, "NORTH")==0){ 
      /*save the direction*/ 
      strcpy_s(direction, sizeof(command), keyword); 
     } 
     else if(strcmp(keyword, "SOUTH")==0){ 
      /*save the direction*/ 
      strcpy_s(direction, sizeof(command), keyword); 
     } 
     else if(strcmp(keyword, "EAST")==0){ 
      /*save the direction*/ 
      strcpy_s(direction, sizeof(command), keyword); 
     } 
     else if(strcmp(keyword, "WEST")==0){ 
      /*save the direction*/ 
      strcpy_s(direction, sizeof(command), keyword); 
     } 
     else{ 
      return; 
     } 
    } 
    return; 
} 

Это действительно важный навык для изучения, поэтому я рекомендую вам попробовать его самостоятельно с помощью других команд.

Надеюсь, что я не использовал синтаксис C++, я не привык писать код c.

2

Независимо от того, как вы приближаетесь к этому, вы просто должны принять его шаг за шагом последовательно, и проверять каждую часть необходимого init DIRECTION X Y ввода вы получите от пользователя. Не имея возможности использовать семейство scanf, это не проблема, вам просто нужно будет полагаться на указатели и арифметику индекса.

Один из подходов в этом отношении - Пройдите указатель вниз по вашей строке ввода, сравнивая значения по мере продвижения. Есть много способов сделать это, но один подход заключается в следующем:

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

#define MAXC 256 

void help() { printf (" format 'init DIRECTION X Y'\n"); } 

int main (void) { 

    enum { EAST, NORTH, WEST, SOUTH } dir; 
    char *names[] = { "EAST", "NORTH", "WEST", "SOUTH" }; 
    char input[MAXC] = ""; 
    char *init = "init"; 
    int x, y; 

    for (;;) { 
     char *p, *ep = NULL; 
     printf ("Enter the commmand: "); 
     fgets (input, MAXC, stdin); 
     if (strncmp (input, init, strlen (init))) { /* compare 'init' 1st */ 
      help(); continue; 
     } 
     if (!(p = strchr (input, ' ') + 1)) { /* find 1st space */ 
      help(); continue; 
     } /* locate 'N', 'S', 'E', 'W' */ 
     while (*p && *p != 'E' && *p != 'N' && *p != 'W' && *p != 'S') p++; 
     if (!*p || !(ep = strchr (p, ' '))) { /* find following space */ 
      help(); continue; 
     } 
     *ep = 0;  /* nul-terminate */ 
     switch (*p) { /* test cardinal names */ 
      case 'E' : if (strcmp (p, "EAST")) { help(); continue; } 
        else dir = EAST; 
        break; 
      case 'N' : if (strcmp (p, "NORTH")) { help(); continue; } 
        else dir = NORTH; 
        break; 
      case 'W' : if (strcmp (p, "WEST")) { help(); continue; } 
        else dir = WEST; 
        break; 
      case 'S' : if (strcmp (p, "SOUTH")) { help(); continue; } 
        else dir = SOUTH; 
        break; 
      default : help(); continue; 
     } 
     *ep = ' ';  /* restore space */ 
     p = ep + 1;  /* advance to next char */ 
     while (*p && (*p < '0' || '9' < *p)) p++; /* find digit */ 
     if (!*p) { 
      help(); continue; 
     } 
     x = *p++ - '0'; /* set x value -- single digit conversion */ 
     while (*p && (*p < '0' || '9' < *p)) p++; /* find digit */ 
     if (!*p) { 
      help(); continue; 
     } 
     y = *p - '0'; /* set y value -- single digit conversion */ 
     break;   /* made it! break out of loop */ 
    } 

    printf ("\n direction '%s', x '%d', y '%d'\n\n", names[dir], x, y); 

    return 0; 
} 

Когда вход не удовлетворяет ваши требования, это полезно, чтобы дать пользователю немного help() напоминать им о правильном формате, они не бесконечно смотрят на мигающий курсор, задаваясь вопросом, как в решающей части решить головоломку.

Пример использование/вывод

$ ./bin/direction 
Enter the commmand: dog food 
format 'init DIRECTION X Y' 
Enter the commmand: inid NORTH 3 6 
format 'init DIRECTION X Y' 
Enter the commmand: init EASY 4 5 
format 'init DIRECTION X Y' 
Enter the commmand: init EAST a 6 
format 'init DIRECTION X Y' 
Enter the commmand: init WEST 6 b 
format 'init DIRECTION X Y' 
Enter the commmand: init SOUTH 4 8 

direction 'SOUTH', x '4', y '8' 

Есть дополнительная валидация можно добавить, но это начало, чтобы ты.

Смежные вопросы