繁体   English   中英

长度未知,输入有多个要求

[英]Unknown length and multiple requirements for input

我正在使用一种名为Objective的结构,该结构包含一个最多8000个字符的char名称(大多数情况下会更短),一个int id,一个int持续时间以及一个称为deps的int数组,在0到9000个元素之间。 这里是:

typedef struct {
unsigned long id, duration, dep [9000];
char name [MAXNAME];
}Objective

我有一些与此结构一起使用的功能,我可以添加,删除,打印等。我需要使用终端指定我要执行的操作,例如添加目标,我需要在终端上编写“添加ID“名称”持续时间deps”。 所以这就是我的问题的开始,以目标的名义,它必须在“”之间,否则命令无效。 我在使用deps数组时也遇到了麻烦,它可以有0到9000个元素,所以我永远不知道有多少个元素,我必须将它们放入将成为目标deps的数组中。 我也不能在参数之间放置两个空格。 输入行的一些示例:

“添加1个“ objective1” 20 2 3 4 5“-这将添加一个ID为1,名称为“ objective1”,持续时间为20并分别为2、3、4和5的目标

“添加1个Objective1 20 2 3 4 5”-无效,因为名称不在“”之间

“ add 1” objective1“ 20”-这将添加一个ID为1,名称为“ objective1”,持续时间为20并且没有deps的目标

“删除1”-删除ID为1的目标

我从以前使用fgets的工作中得到了这一点:

char input[82], col [6], na [80];    unsigned long a, b;
double c;


while(input[0] != 'q'){
  if(fgets(input, sizeof(input), stdin)){
      if(input[0] == 'p' && input[1] == '\n' && input[2] == '\0'){
        list(matrix);
    }
    else if(input[0] == 'i' && input[1] == '\n' && input[2] == '\0'){
        carac(matrix);
    }
    else if((sscanf(input, "%c %lu %lu %lf\n", &input[0],
     &a, &b ,&c) == 4)){
        adds(a, b, c, matrix);
    }
    else if(input[0] == 'l' && (sscanf(input, "%*c %lu\n", &a) == 1)){
        printLine(a , matrix);
    }
    else if(input[0] == 'c' && (sscanf(input, "%*c %lu\n", &a) == 1)){
        printColumn(a , matrix);
    }
    else if(input[0] == 'z' && (sscanf(input, "%*c %lf\n", &c) == 1)){
        zero(c , matrix);
    }
    else if(input[0] == 'o' && input[1] == '\n' && input[2] == '\0'){
        sortLine(matrix);
    }
    else if(input[0] == 'o' && (sscanf(input, "%*c %s\n", col) == 1) && strcmp(col, "column") == 0){
        sortColumn(matrix);
    }
    else if(input[0] == 'w' && input[1] == '\n' && input[2] == '\0'){
        file(matrix);
    }
    else if(input[0] == 'w' && (sscanf(input, "%*c %s\n", na) == 1) ){
        newFile(na, matrix);
    }
} 
}

但是在这种情况下,它必须有很大的不同,“”之间的名称,未知数量的deps元素以及参数之间的空格使这对我来说真的很难,是否有人对我如何做到或如何解决提出建议?我上面列出的问题之一?

首先,关于用户输入的注释:我同意@ryyker,请尝试提出一种易于解析的用户输入格式。 从一开始就试图使输入变得太灵活会妨碍您,而您应该专注于程序的逻辑。 但是也许您不是选择格式的人,所以继续前进...

您选择定义结构并使用fgets()不错。 但是,您将所有内容放在一个while()构造中,这无助于组织代码。 我不会为您提供完整的代码,而只会提供有关如何组织代码的指针。

我建议您分开:

  1. 将用户输入读入缓冲区。
  2. 从该缓冲区中提取命令。
  3. 检查用户输入是否正确。
  4. 解释命令并执行程序逻辑。

第1部分: scanf()不好,因为您不知道行的长度。 在相当长的缓冲区上继续使用fget,例如:

char buf[1024];

// ...

/* Maybe you'll want to use something else than fgets()
 * later on. Encapsulate "reading from user" in a function. */
void read_user_input(char **buf, int size) {

    *buf = fgets(*buf, size, stdin);
}

第2部分和第3部分:编写小函数以从缓冲区中提取标记,并检查例如每个标记之间是否用单个空格分隔,或者检查用户是否在“名称”周围使用了引号。

/* Return the index of the first character of the next token
 * in a string. Start searching from "idx".
 * Tokens are separated by spaces. */
int next_token(char *buf, int idx, const int size) {

    while (idx < size && is_whitespace(buf[idx])) {
        ++idx;
    }

    if (idx == size) {
        return -1; // no token here
    }
    else {
        return idx;
    }
}

// ...

int check_spacing(char *buf, int size) {

    /* Extract tokens, maybe fill struct Objective along
     * the way. */
    int idx = 0;

    while (idx < size) {
        int next_token_idx = next_token(buf, idx, size);

        if (next_token_idx - idx > 1) {
            // More than 1 space, not good!
        }
    }
}

第4部分:您已经完成了工作:adds(),printLine(),printColumn()...

一旦切入了简洁的小函数,编写主循环就会容易得多:

main(int argc, char *argv[]) {

    const int size = 1024;
    char buf[size];

    Objective obj = null;

    // Read as long as the line is not finished.
    do {
        read_user_input(buf, size);
        // Check that tokens are valid
        // Build a struct Objective along the way
        // obj = ... ;
        // Also fetch the command: "add", "remove"...
    } while (! contains_newline(buf));

    // Now that you're confident user input is OK,
    // you can execute command happily
    if (strcmp(command, "add") == 0) {
        // Add an objective
    }
    else if (strcmp(command, "remove") {
        // Remove an objective
    }
    else if (strcmp(command, "i") {
        carac(matrix);
    }
    // etc.
}

暂无
暂无

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

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