简体   繁体   English

使用scanf读取格式化的输入

[英]Reading a formatted input using scanf

I want read from stdin some variables with their values using scanf.The input is formatted as below: 我想使用scanf从标准输入中读取一些变量及其值,输入格式如下:

MY_VARIABLE_BEGIN
var1 
var2
...
MY_VARIABLE_END
MY_VALUES_BEGIN
val1
val2
...
MY_VALUES_END 

The input is composed of 2 parts: 输入由两部分组成:

part 1:Name of the variables this part is delimited by MY_VARIABLE_BEGIN ,MY_VARIABLE_END 第1部分:变量的名称,此部分由MY_VARIABLE_BEGIN,MY_VARIABLE_END分隔

part 2:The values of each variable this part is delimited by MY_VALUES_BEGIN, MY_VALUES_BEGIN 第2部分:此部分的每个变量的值均由MY_VALUES_BEGIN,MY_VALUES_BEGIN分隔

The problem is that i don't know the number of the variables and their values. 问题是我不知道变量的数量及其值。 Can any body help me find the right format to pass to scanf function,or if there is any other solution to solve the problem? 有谁可以帮助我找到传递给scanf函数的正确格式,或者是否有其他解决方案来解决该问题?

Example of input 输入示例

MY_VARIABLE_BEGIN
var1 
var2
MY_VARIABLE_END
MY_VALUES_BEGIN
1
5
MY_VALUES_END 

I should read 2 variables var1 and var2, var1=1 and var2=5 我应该读取2个变量var1和var2,var1 = 1和var2 = 5

You can try this 你可以试试这个

char line[256];
fgets(line, sizeof(line), stdin);
if (strcmp(line, "MY_VARIABLE_BEGIN") {
    do {
        fgets(line, sizeof(line), stdin);

        // . . . do something with the line

    } while (strcmp(line, "MY_VARIABLE_END"));
}

Not sure if it'll work. 不确定是否会工作。

Doing it with scanf is a pain. scanf这样做很痛苦。 Why not use a regular expression from C ? 为什么不使用C正则表达式 Here's a complete working program to show how easy it can be. 这是一个完整的工作程序,以显示它很容易。 Start by reading all the data into a single string, data. 首先将所有数据读取到单个字符串data中。 I'm just using a constant. 我只是使用一个常数。 Compile your pattern with regcomp , then apply it with regexec to your string. 使用regcomp编译您的模式,然后使用regexec将其应用于您的字符串。 It returns an array of matched groups which correspond to the (.*?) parts of the pattern. 它返回一组与模式的(.*?)部分相对应的匹配组。 Group 0 is of no interest in this example as it is just the entire data. 在该示例中,组0无关紧要,因为它只是整个数据。

For the other 2 groups, you get the indexes in the string of the start and end of the match. 对于其他两个组,您将在比赛开始和结束的字符串中获取索引。 Use strndup() to copy these. 使用strndup()复制这些内容。 Use strtok to split this dup on the newline \\n character. 使用strtok在换行符\\n上拆分此dup You have in ptr at each point each var and value. 你必须在ptr在每个点每个变种和价值。

/* regex example. meuh on stackoverflow */
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

void pexit(char *str){
    extern int errno;
    perror(str);
    exit(errno);
}
#define NUMMATCH (1+2) /* max num matching capture groups in pattern */
main(int argc, char **argv){
    regex_t myexpn;
    regmatch_t matches[NUMMATCH] = {0};
    int rc,i;
    char *data = "\n\
MY_VARIABLE_BEGIN\n\
var1 \n\
var2\n\
...\n\
MY_VARIABLE_END\n\
MY_VALUES_BEGIN\n\
val1\n\
val2\n\
...\n\
MY_VALUES_END\n\
";
    char *delim = "\n";
    char *pattern = "\\s*MY_VARIABLE_BEGIN\\s*(.*?)MY_VARIABLE_END.*?MY_VALUES_BEGIN\\s*(.*?)MY_VALUES_END";
    /* need REG_EXTENDED to use () in pattern else \\(\\) */
    rc = regcomp(&myexpn, pattern, REG_EXTENDED);
    if(rc!=0)pexit("regcomp");
    rc = regexec(&myexpn, data, NUMMATCH, matches, 0);
    if(rc==REG_NOMATCH)printf("no match\n");
    else{
        for(i = 1;i<NUMMATCH;i++){ /* ignore group 0 which is whole match */
            if(matches[i].rm_so!=-1){
                char *dup = strndup(data+matches[i].rm_so, matches[i].rm_eo-matches[i].rm_so);
                printf(" match %d %d..%d \"%s\"\n",i, matches[i].rm_so, matches[i].rm_eo, dup);
                char *ptr = strtok(dup, delim);
                while(ptr){
                    printf("    token: %s\n",ptr);
                    ptr = strtok(NULL, delim);
                }
                free(dup);
            }
        }
    }
    regfree(&myexpn);
}

This prints out: 打印输出:

 match 1 19..34 "var1 
var2
...
"
    token: var1 
    token: var2
    token: ...
 match 2 66..80 "val1
val2
...
"
    token: val1
    token: val2
    token: ...

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

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