1

I'm learning C language, I'm having trouble with my program.

So, I have this program called TEST this program should allow me to read the argument either with argv[] or by using the input stream $ TEST < argsTest.json.

argsTest.json :
{
"a" = 2,
"b" = 3
}

to simplify my question I will use this simple program :

Struct {
    int a;
    int b;
} number;

int main(int argc, char **argv) {
    json_t * root;
    struct number numbers;
    int c = 0, i = 0 , result;
    char str[1024]; // I'm not using malloc just to simplify my question
    // default values
    numbers.a = 0;
    number.b = 0;

    if (argc == 1 && !feof(stdin)) {
        while((c = fgetc(stdin)) != EOF) {
            str[i]=c;
            ++i;
        }
        str[i] = '\0';

        .... // code that use jansson library to extract value

        /** let's suppose we have extracted the two value int json_a
          * and int json_b.
          */

        numbers.a = json_a;
        numbers.b = json_b;

    } else if (argc == 3) {
        scanf("%d", numbers.a);
        scanf("%d", numbers.b);
    }

    result = numbers.a + number.b;
    printf("%d\n", result);

    return 0;
}

So, I'm trying to implement three behaviors :

  1. $ TEST it should display 0 ( we used the default values).
  2. $ TEST < argsTest.json display 5.
  3. $ TEST 4 3 display 7.

My problem is that if statement if (argc == 1 && !feof(stdin)) , actually $ TEST and $ TEST < argsTest.json have the same statement argc == 1, so when run $ TEST it bug because he enters the first condition.

I want an if statement that will check if the input stream is empty and having 0 argument, so I can implement the first case without getting in the if statement.

Thank you.

5
  • 1
    Possible duplicate of Checking the stdin buffer if it's empty Commented Mar 19, 2018 at 23:53
  • 1
    When you run TEST, stdin is not empty. Instead, stdin is whatever you enter on the terminal. You will have to press Ctrl+D for the terminal input to be considered empty. I would strongly encourage you to rethink your interface and work with the system instead of against it. Canonical behavior is easier to implement and easier to use. Commented Mar 19, 2018 at 23:58
  • @Tim No it's not the same , it is pretty similar i agree but in his case he read the EOF from the buffer so he had to send it with` Ctrl+d` , in my case i want to do it automatically without getting in the if statement . Even if i have to change the if statement. Commented Mar 20, 2018 at 0:02
  • @thatotherguy Could you provide me with a small example if possible. like i said i'm pretty new to C prog.language. Commented Mar 20, 2018 at 0:07
  • @Haskell-newb How does the computer know whether you're not going to type something, or whether you are going to type something but you haven't yet? Commented Mar 20, 2018 at 2:12

1 Answer 1

2

The general idea is

  • check argc first to see if you should use the values in argv
  • check whether the terminal is interactive
    • if it is then just print 0
    • if it's not interactive then you can read from stdin

The problem is that there's no portable way to check if stdin is interactive. However, on POSIX systems, you can use the isatty function, as explained in this question.

So assuming that you are on a POSIX system, the code looks like this:

int main(int argc, char *argv[])
{
    struct number numbers;

    if (argc == 3)
    {
        if (sscanf(argv[1], "%d", &numbers.a) == 1 && sscanf(argv[2], "%d", &numbers.b) == 1)
            printf("From argv the answer is %d\n", numbers.a + numbers.b);
        else
            printf("Bad strings in argv\n");
    }
    else if (isatty(STDIN_FILENO))
    {
        printf("Nothing in argv or on stdin, so the answer is 0\n");
    }
    else
    {
        if (scanf("%d%d", &numbers.a, &numbers.b) == 2)
            printf("From stdin the answer is %d\n", numbers.a + numbers.b);
        else
            printf("Found junk on stdin\n");
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank for those details, i apreciate that very much luckily i'm on a POSIX system.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.