Home > Back-end >  How to read an input given by a driver function
How to read an input given by a driver function

Time:04-06

I am working on a project that will have a driver program redirect its output into the standard input of my program, how would I be able to scan what this program is feeding into my program and have my program respond accordingly. I was thinking of using scanf, would that work?

Additional info: In the first line of the input (out of many lines), the driver gives a number ending in a new line character (\n). Depending on that number, my program will parse the rest of the lines in the input and output a response. Each line will be a string of random letters and my program will need to dynamically allocate memory for each string. These strings will be part of a struct in a linked list.

CodePudding user response:

You can treat the input just like regular console input, all the console stdio input calls will work. Just dont try to have a conversation with it - ie dont go

Enter foodle count : dd
Invalid number
Enter Foodle count :

becuase there is nobody on the other end

CodePudding user response:

It is generally recommended to use a more robust method than scanf, as it is full of edge cases, and offers little in the way of recovering from bad input.

A beginners' guide away from scanf() is a decent read, although I would offer stricter advice: forget scanf exists.

Given the requirement of

Each line will be a string of random letters and my program will need to dynamically allocate memory for each string. These strings will be part of a struct in a linked list.

POSIX getline (or getdelim) is a solid choice, if available. This function handles reading input from a file, and will dynamically allocate memory if requested.

Here is an example skeleton program, with functionality vaguely similar to what you have described.

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>

char *input(FILE *file) {
    char *line = NULL;
    size_t n;

    if (-1 == getline(&line, &n, file))
        return NULL;

    return line;
}

size_t parse_header(char *header) {
    return 42;
}

void use_data(char *data) {
    free(data);
}

int main(void) {
    char *header = input(stdin);
    char *data;

    if (!header)
        return EXIT_FAILURE;

    size_t lines_expected = parse_header(header);
    size_t lines_read = 0;

    free(header);

    while ((data = input(stdin))) {
        lines_read  ;
        use_data(data);
    }

    if (lines_read != lines_expected)
        fprintf(stderr, "Mismatched lines.\n");
}

If POSIX is not available on your system, or you just want to explore alternatives, one of the better methods the standard library offers for reading input is fgets. Combined with malloc, strlen, and strcpy, you have will have roughly implemented getline, but do note the caveats in the provided fgets manual.

While scanf is a poor choice for both reading and parsing input, sscanf remains useful for parsing strings, as you have greater control over the state of your data.

The strtol/strtod family of functions are usually preferred over atoi style functions for parsing numbers, though they can be difficult to use properly.

  • Related