Thread: Unknown length of console input

  1. #1
    Registered User
    Join Date
    Apr 2018
    Posts
    16

    Unknown length of console input

    I'm working with a struct called objective, that consists of a char name with a max of 8000 characters, an int id, an int duration and an array of ints called deps that can have between 0 and 9000 elements.
    I have some functions to work with this struct, I can add one, can remove, can print, etc.
    I need to use the terminal to specify what I want to do, for example to add an objective i need to write on the terminal " add id "name" duration deps".
    So this is where my problem begins, in the name of the objective, it has to be between " ", if not the command isn't valid. I'm also having trouble with deps array, it can have between 0 and 9000 elements so i never know how many there are, i have to put them into an array that will be the deps of the objective. I also can't put two spaces between arguments.

    I have this from a previous work using fgets:

    Code:
     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);
            }
        } 
    }
    But it will not help me this time, this command has a lot of requirements to be valid and i'm having a lot of trouble, does anyone have some advice on how to do this?

  2. #2
    Registered User john.c's Avatar
    Join Date
    Dec 2017
    Posts
    344
    You seem to be suggesting that the name could be thousands of characters long and that it could be followed by thousands of integers. Is that the case? What kind of robot user is going to type all of that in?

    Give some real examples of input lines.
    Simplicity is the ultimate sophistication.

  3. #3
    Registered User
    Join Date
    Apr 2018
    Posts
    16
    Sorry if I didn't explain all that well... the name can be 8000 characters long but most of the time it wont be the case, i have some test files with a lot of deps.
    Here some examples:

    "add 1 "objective1" 20 2 3 4 5" - this adds an objective with id 1, name "objective1", duration 20 and deps 2, 3, 4 and 5

    "add 1 objective1 20 2 3 4 5" - this is invalid because the name is not between " "

    "add 1 "objective1" 20" - this adds an objective with id 1, name "objective1", duration 20 and with no deps

    "remove 1" - removes objective with id 1

    I have the fuctions to add, remove, etc done but my issue is really is the inputs because of the many requirements.

  4. #4
    Registered User john.c's Avatar
    Join Date
    Dec 2017
    Posts
    344
    Maybe something like this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    typedef struct Objective {
        char *name;
        int   id;
        int   duration;
        int   ndeps;
        int  *dep;
    } Objective;
    
    void print_objective(Objective *o) {
        printf("Id  : %d\n", o->id);
        printf("Name: %s\n", o->name);
        printf("Duration: %d\n", o->duration);
        if (o->ndeps == 0)
            printf("no deps\n");
        else {
            printf("deps: ");
            for (int i = 0; i < o->ndeps; i++)
                printf("%d ", o->dep[i]);
            printf("\n");
        }
    }
    
    char *readline(FILE *fin) {
        char buf[1000];
        char *line = NULL;
        size_t size = 0;
        while (fgets(buf, sizeof buf, fin) != NULL) {
            size_t len = strlen(buf);
            line = realloc(line, size + len + 1);
            strcpy(line + size, buf);
            size += len;
            if (line[size - 1] == '\n') {
                line[size - 1] = '\0';
                break;
            }
        }
        return line;
    }
    
    bool do_add_command(const char *line, Objective *o) {
        char name[8001];
        int dep[9001];
        int n;
    
        if (sscanf(line, "%d%n", &o->id, &n) != 1) {
            printf("No id\n");
            return false;
        }
    
        char ch = '\0';
        sscanf(line += n, " %c%n", &ch, &n);
        if (ch != '"') {
            printf("No starting quote\n");
            return false;
        }
    
        *name = '\0';
        if (sscanf(line += n, "%8000[^\"]%n", name, &n) != 1 || !*name) {
            printf("No name\n");
            return false;
        }
        int sz = strlen(name);
        o->name = malloc(sz + 1);
        strcpy(o->name, name);
    
        ch = '\0';
        sscanf(line += n, " %c%n", &ch, &n);
        if (ch != '"') {
            printf("No ending quote\n");
            return false;
        }
    
        if (sscanf(line += n, "%d%n", &o->duration, &n) != 1) {
            printf("No duration\n");
            return false;
        }
    
        o->ndeps = 0;
        while (sscanf(line += n, "%d%n", &dep[o->ndeps], &n) == 1)
            o->ndeps++;
        if (o->ndeps > 0) {
            size_t sz = o->ndeps * sizeof *o->dep;
            o->dep = malloc(sz);
            memcpy(o->dep, dep, sz);
        }
    
        return true;
    }
    
    int main() {
        char *line;
        while ((line = readline(stdin)) != NULL) {
    
            char command[50];
            int n = 0;
            sscanf(line, "%49s%n", command, &n);
    
            if (strcmp(command, "add") == 0) {
                Objective o;
                if (do_add_command(line + n, &o))
                    print_objective(&o);
            }
            else if (strcmp(command, "remove") == 0) {
            }
            else if (strcmp(command, "quit") == 0) {
                break;
            }
            else {
                printf("Unrecognized command\n");
            }
    
            free(line);
        }
    
        return 0;
    }
    Simplicity is the ultimate sophistication.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 04-14-2018, 02:21 AM
  2. input string of unknown length in c
    By Obvious Guy in forum C Programming
    Replies: 4
    Last Post: 04-13-2018, 02:46 PM
  3. How do I save a returned of unknown length?
    By Philip Rego in forum C Programming
    Replies: 3
    Last Post: 09-15-2014, 07:02 PM
  4. Calculating Sum of Integers of Unknown Length
    By egnorth in forum C++ Programming
    Replies: 3
    Last Post: 10-28-2010, 04:31 PM
  5. reading a file of unknown length
    By the bassinvader in forum C Programming
    Replies: 2
    Last Post: 07-12-2006, 03:06 PM

Tags for this Thread