Mossi
Mossi

Reputation: 81

stdout/stdin and Parameters

I'm having a little problem with my programs and I don't know how to solve it. My programs work fine as long as I don't include getopt(without arguments).

I wrote 2 simple programs Server&Client

The Server writes numbers in stdout and the Client should read them with stdin.

Furthermore the programs should be able to get called with arguments(parameters).

For example a call of the program looks like that:

Terminal: ./Server -f72 | ./Client -r22

If I run the program then it just prints the "Her is r" with the argument "22" and "Waiting for Server", but it should print the numbers from the server

I am not able to find the mistake. I would really appreciate your help. Thanks in advance to all who read that.

Server:

int main(int argc , char *argv[])
{
    int i;
    FILE *ziel;
    ziel=stdout;

    int option;
    char buf[50];

    while ((option = getopt(argc, argv,"f:tr:d:j")) != -1)
    {
        switch (option)
        {
            case 'f' :
                strcpy(buf,optarg);
                break;
            case 't' :              
                break;
            case 'r' :
                strcpy(buf,optarg);
                break;
            default:
                //printf("1ERROR");
                exit(EXIT_FAILURE);
        }
    }

    for(i=1;i>0;i++)
    {
        fprintf(ziel,"%d\n",i);
        sleep(1);
    }
    return 0;
}

Client:

int main(int argc , char *argv[])
{
    FILE* cl;
    cl=stdin;
    int i;
    int zahl[10];
    int option;
    char buf[50];

    while ((option = getopt(argc, argv,"f:tr:")) != -1)
    {
        switch (option)
        {
            case 'f' :
                puts("Here is f");
                strcpy(buf,optarg);
                puts(buf);
                break;
            case 't' :
                puts("Here is t");
                break;
            case 'r' :
                puts("Here is r");
                strcpy(buf,optarg);
                puts(buf);
                break;
            default:
                printf("ERROR");
                exit(EXIT_FAILURE);
        }
    }

    puts("Waiting for Server");
    for(i=0;i<10;i++)
    {
        fscanf(cl,"%d",&zahl[i]);
        printf("Received %d\n ",zahl[i]);

    }

    return 0;
}

Upvotes: 1

Views: 624

Answers (1)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140168

The problem in your example has nothing to do with getopt. It's about output buffering.

If you wait long enough, a burst of numbers should appear in one go.

I made it work by modifying the server program

  • removing the sleep(1)
  • or using fflush(stdout); after the fprintf

  • When printing in the terminal, the output is flushed when a linefeed is encountered, which explains why it works.

  • When printing in a redirected output, buffering takes place. You have to explicitly flush the buffer (the C library could decide to flush anyway, but that's not what's happening here)

You cannot control that from your client. Even piping the server to more doesn't work in your case.

Read also here: Does reading from stdin flush stdout?

Note: you could fool your server program into believing it's writing in a tty, it's a bit hacky but could work:

Pretend to be a tty in bash for any command

(I currently don't have a Windows solution)

Upvotes: 1

Related Questions