web-dev-qa-db-fra.com

Printf et fprintf (stdout,) de C n'impriment pas

C'est un peu étrange. Mon code ne produisait pas ce que je pensais qu'il devrait. J'ai ajouté des déclarations imprimées à différentes étapes pour voir où cela allait mal. Toujours rien. J'ai donc ajouté une instruction printf au début de main. C'est là que je suis devenu vraiment confus.

J'ai donc supposé qu'il se passait quelque chose de drôle avec les descripteurs de fichiers. J'ai changé le printf en fprintf. Toujours rien. L'impression sur stderr avec fprintf fonctionne! Pourquoi cela arrive-t-il?

Suppression de tout le corps de main sauf l'instruction initiale d'impression et le retour s'imprime.

Code

int main(void) {
    fprintf(stdout, "STARTED!");
    //Create an Internet domain socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    //If this fails exit and print the error
    if (sockfd == -1) {
        printf("Error %d, cannot create socket", errno);
        return 1;
    }
    printf("SOCKET CREATED!");

    //Creates a socket address
    struct sockaddr_in  addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = INADDR_ANY;

    //Attempts to bind to the socket address, again prints to error if this fails.
    if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
    {
        printf("Error %d, cannot bind", errno);
        return 1;
    }

    //Starts Listening for a client
    if (listen(sockfd, 1) == -1)
    {
        printf("Error %d, cannot listen", errno);
        return 1;
    }

    //If all is successful, server is operational
    while(1)
    {
        //Creates a file descripter for the connection
        int connfd;
        //And a socket address for the client
        struct sockaddr_in cliaddr;
        socklen_t cliaddrlen = sizeof(cliaddr);
        //If a connection attempt is made accepts it.
        connfd = accept(sockfd, (struct sockaddr *) &cliaddr, &cliaddrlen);
        if (connfd == -1) {
            //If the connection fails print an error
            printf("Error %d, cannot accept connection", errno);
            continue;
        }

        //Otherwise process the request
        else {
            printf("CONNECTED!");
            char end;
            end = 1;
            while (end)
            {
                process_request(connfd);
                end = 0;
            }
        }
        close(connfd);

    }
    close(sockfd);
    return 0;
}
13
Hector

La sortie est souvent mise en mémoire tampon par le système. Vous pouvez appeler fflush, mais parfois, selon le fonctionnement de la mise en cache, il suffit de terminer la sortie par une nouvelle ligne. Alors essayez de changer

fprintf(stdout, "STARTED!");

à

fprintf(stdout, "STARTED!\n");

Et, si cela n'aide pas,

fprintf(stdout, "STARTED!\n");
fflush(stdout)

(Et stderr n'est souvent pas mis en cache, car vous voulez voir les erreurs immédiatement.)

Enfin, vous verrez la sortie lorsque le programme se terminera (car les choses sont alors vidées), ce qui explique probablement le reste du comportement.

27
andrew cooke