2017-07-11 6 views
1
#include<string.h> 
#include<stdio.h> 
#include<stdlib.h> 

int main(){ 
    int num; 
    scanf("%d",&num); // The input is 3 so i use it to simplify the question 
    char array[num][1000]; 
    fgets(array[0],1000,stdin); 
    fgets(array[1],1000,stdin); 
    fgets(array[2],1000,stdin); 
    printf("%s %s %s",array[0],array[1],array[2]); 
} 

La première entrée, c'est-à-dire pour scanf, est 3, puis l'entrée i mahatma et le gandhi. Maintenant, il devrait demander une autre entrée pour les derniers fgets mais le programme finit d'imprimer mahatma gandhi. Cependant je n'utilise pas scanf alors le résultat est correct. Si possible, veuillez fournir un code. P.S- J'utilise fgets pour la 1ère fois, donc il peut y avoir une erreur très basique.prend seulement 2 entrées bien qu'il ait 3 fuels

+0

@xing Je soupçonnais que le printf de sameas imprimait un \ n. comment puis-je le corriger –

+0

@xing pouvez-vous fournir un code pour cela s'il vous plaît –

Répondre

0

suffit de fournir un espace comme celui-ci scanf()

scanf("%d ",&num);

cela fera appeler fgets trois fois (Juste pour ce cas comme indiqué par Peter). Cela se produit parce que lorsque vous appuyez sur la touche ENTRÉE après scanf() dans STDIN le tampon \n est stocké et cela obtient dans le premier appel fgets().

+0

merci yaar, une telle solution éloquente.comment puis-je imprimer tous les noms obtiennent par fgets dans une ligne comme fgets stocke aussi \ n et donc en utilisant printf tous sont imprimés sur de nouvelles lignes. –

+0

aucun problème bai;) –

+2

'scanf ("% d ", &num);' consommera non seulement un seul '' \ n'' suivant, mais tous les espaces blancs suivants. Ceci n'est pas utile si la première des 3 lignes suivantes commence avec un espace blanc – chux

2

La raison, comme xing a noté dans les commentaires, est que scanf() laisse une nouvelle ligne dans le flux (représenté par le descripteur de fichier stdin) qui sera lu par le premier appel de fgets(), faisant revenir immédiatement. La solution générale est de ne pas mélanger une entrée formatée (comme scanf()) avec une entrée orientée ligne (comme fgets()) sur le même flux d'entrée, car ils interagiront de manière inattendue. Votre exemple ici (scanf() en laissant une nouvelle ligne à lire, et fgets() retournant immédiatement en raison de la rencontre de la nouvelle ligne) est l'une des nombreuses conséquences possibles du mélange des styles d'entrée sur le même flux.

Une façon consiste à utiliser fgets() pour lire des données dans une chaîne, puis de lire une int à partir de cette chaîne à l'aide de sscanf(). L'interaction avec stdin utilise UNIQUEMENT fgets().

Une autre option serait de changer tous les usages de fgets() pour utiliser scanf(). Cela nécessitera de trouver un format raisonnable (en gardant à l'esprit que scanf() arrête de lire quelque chose quand il rencontre des espaces - bien qu'il y ait des spécificateurs de format qui changent cela).

Le conseil d'ajouter un espace à la chaîne de format scanf() est erroné. Cela fonctionne pour des cas spécifiques (comme celui-ci), mais pas pour d'autres. Par exemple, si vous faites une boucle de la forme

// assume variables declared as in the OP's question 

while (some_condition_that_is_true_more_than_once()) 
{ 
    scanf("%d ",&num); 
    fgets(array[0],1000,stdin); 
    fgets(array[1],1000,stdin); 
    fgets(array[2],1000,stdin); 
} 

il y aura encore une interaction potentielle (en fonction de ce que les entrées de l'utilisateur) qui donne des résultats inattendus en raison de l'interaction du dernier appel de fgets() dans la boucle avec l'appel scanf() dans l'itération suivante.

+0

O_O Voilà comment vous devenez LÉGENDE _/\ _ –

+0

@peter comment puis-je imprimer tous les noms obtenus par fgets dans une ligne comme fgets stocke également \ n et par conséquent printf tout est imprimé sur de nouvelles lignes Comment puis-je supprimer le \ n –

+0

@xing merci qui a résolu mon problème –

1

Envisagez d'utiliser fgets pour toutes les entrées. Analyser au besoin avec sscanf ou autres.
Vérifiez le retour de fgets et sscanf car cela indique des problèmes.
La boucle do/while continue jusqu'à ce qu'un entier positif soit traité.
Inclure des invites pour clarifier les entrées attendues.

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
    char input[50] = ""; 
    int num = 0; 
    int loop = 0; 
    int valid = 0; 

    do { 
     printf ("enter an integer\n"); 
     if (fgets (input, sizeof input, stdin)) { 
      if (1 != (valid = sscanf (input, "%d", &num))) {// 1 means successful scan on an integer 
       valid = 0; 
       printf ("try again to enter an integer\n"); 
      } 
     } 
     else {// fgets could not get input 
      fprintf (stderr, "problem with input\n"); 
      return 0; 
     } 
    } while (!valid || num < 0); 

    char array[num][1000]; 

    for (loop = 0; loop < num; loop++) { 
     printf ("enter text for array[%d]\n", loop); 
     if (fgets(array[loop],sizeof array[loop], stdin)) { 
      array[loop][strcspn(array[loop], "\n")] = '\0';// remove trailing newline if any 
     } 
     else { 
      fprintf (stderr, "problem with input\n"); 
      return 0; 
     } 
    } 

    for (loop = 0; loop < num; loop++) { 
     printf("%s ", array[loop]); 
    } 
    printf("\n"); 
}