C-get来自用户的特定输入

时间:2016-04-04 07:51:28

标签: c stdin

我需要从用户那里得到一些具体的输入(用户需要输入“init 3 4 NORTH”,3是X(int type)的值,4是Y(int type)的值,NORTH是值direction(枚举类型)init是必须输入的命令。)如果用户只输入“3 4 NORTH”,程序将不会执行任何操作。

我不允许使用任何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值,得到方向值。 我希望我的解释足够清楚,希望任何人都可以分享他们的想法。

4 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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'

您可以添加其他验证,但这是让您前进的开始。

答案 2 :(得分: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代码。

答案 3 :(得分: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
    }
}