0
votes

I want read from stdin some variables with their values using scanf.The input is formatted as below:

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

part 2:The values of each variable this part is delimited by 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?

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
Are the beginning and end strings artificial or really written to stdin? Can you be absolutely sure every variable has a value? - cadaniluk
You'll have to read each line as a string (using e.g. fgets(3)), then scan the start of the string for the MY_ part, and if not, parse the variable (using e.g. sscanf(3) and store the variable into an array (increasing the array as necessary with e.g. realloc(3)). This is a very general way to do; you may be able to use some constraints on your input data. - user707650
Please provide a concrete example, using real numbers and variables, so I can provide you a C code for reading it. - Mihai Hangiu
@cad 1) beginning and end strings( MY_VARIABLE_BEGIN,MY_VARIABLE_END ,MY_VALUES_BEGIN,MY_VALUES_END )are really written in the stdin they serve as delimiters.2)i assume that every variable has value - fedi
@fedi Yes they are delimiters but what content is between them .Please give information about it . - ameyCU

2 Answers

0
votes

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.

0
votes

Doing it with scanf is a pain. Why not use a regular expression from 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. I'm just using a constant. Compile your pattern with regcomp, then apply it with regexec to your string. 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.

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. Use strtok to split this dup on the newline \n character. You have in ptr at each point each var and value.

/* 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: ...