web-dev-qa-db-fra.com

Je ne suis pas capable de vider stdin

Comment vider le stdin ?? 

Pourquoi ne fonctionne-t-il pas dans l'extrait de code suivant?

#include <string.h>
#include <stdio.h>
#include <malloc.h>
#include <fcntl.h>

int main()
{
        int i=0,j=0, sat;
        char arg[256];
        char * argq;
        argq = malloc(sizeof(char)*10);

        printf("Input the line\n");
        i=read(0, arg, sizeof(char)*9);
        arg[i-1]='\0';
        fflush(stdin);

        i=read(0, argq, sizeof(char)*5);
        argq[i-1]='\0';

        puts(arg);
        puts(argq);

        return 0;
}

Maintenant, si je donne l'entrée comme 11 caractères, seulement 9 devraient être lus mais les deux caractères restants dans le stdin ne sont pas vidés et lus encore dans l'argq. Pourquoi?

Entrée: 123 456 789

Sortie: 123 456 89

Pourquoi est-ce que je reçois ce 89 comme sortie?

15
Subodh Asthana

Je pense que fflush n'est utilisé qu'avec les flux de sortie. 

Vous pouvez essayer fpurge ou __fpurge sur Linux. Notez que fpurge n'est pas standard et n'est pas portable. Il peut ne pas être disponible pour vous.

Extrait d'une page de manuel Linux fpurge : Habituellement, vouloir supprimer les mémoires tampons est une erreur.

La solution la plus portable pour rincer la stdin serait probablement la suivante:

int c;
while ((c = getchar()) != '\n' && c != EOF);
31
jschmier
12
jamesdlin
int c;
while((c = getchar()) != '\n' && c != EOF);

Est-ce que je voudrais effacer le tampon d'entrée.

10
user1831086

Comment vider le stdin ?? 

Le vidage des flux d’entrée appelle un comportement non défini. N'essaye pas.

Vous ne pouvez vider que les flux de sortie.

3
dirkgently

Vous remplacez le dernier élément de l'entrée dans arg par '\0'. Cette ligne devrait plutôt être arg[i]='\0'; (après une erreur et une vérification des limites, il vous manque). 

Les autres ont déjà commenté la partie rinçage.

2
Nikolai Fetissov

Vous ne pouvez pas nettoyer stdin sous Linux sans vous heurter à des scénarios dans lesquels la commande commencera à attendre une entrée dans certains cas. La solution consiste à remplacer std :: cin par readLineToStdString ():

void readLine(char* input , int nMaxLenIncludingTerminatingNull )
{
    fgets(input, nMaxLenIncludingTerminatingNull , stdin);

    int nLen = strlen(input);

    if ( input[nLen-1] == '\n' )
        input[nLen-1] = '\0';
}

std::string readLineToStdString(int nMaxLenIncludingTerminatingNull)
{
    if ( nMaxLenIncludingTerminatingNull <= 0 )
        return "";

    char* input = new char[nMaxLenIncludingTerminatingNull];
    readLine(input , nMaxLenIncludingTerminatingNull );

    string sResult = input;

    delete[] input;
    input = NULL;

    return sResult;
}

Cela vous permettra également de saisir des espaces dans la chaîne std :: cin.

0
Sunny127