2017-05-04 1 views
1

Je veux utiliser une boucle ici. Mais mes seconds fgets ne fonctionnent pas correctement!
En 1ère boucle c'était bon! mais après ça il saute ses deuxièmes fgets!
Comment le réparer?
MerciComment utiliser les fgets dans une boucle?

#include<stdio.h> 
#include<string.h> 
int main (void) 
{ 
char first_line[1000]; 
char second_line[2]; 
int i,n,j,k; 
int count=0,flag=0; 
scanf("%d ",&k); 
for(int m=0; m<k; m++) 
{ 
    fgets(first_line, 1000, stdin); 
    fgets(second_line, 2, stdin); 
    for(i=0; i<strlen(first_line); i++) 
    { 
     if(second_line[0]==first_line[i]) 
     { 
      flag=1; 
      count++; 
     } 
    } 
    first_line[strlen(first_line)-1] = '\0'; 
    if(flag==1) 
     printf("Occurrence of '%c' in %s = %d",second_line[0],first_line,count); 

    else 
     printf("%c isn't present",second_line[0]); 
    count=0; 
    flag=0; 
} 

return 0; 
} 
+5

'char second_line [2];' ne peut contenir qu'un seul caractère réel. Donc, s'il y a une lettre et un saut de ligne sur une ligne, une nouvelle ligne sera entrée dans 'fgets' de la prochaine boucle. – BLUEPIXY

+1

Je l'ai déjà fait une fois! http://stackoverflow.com/q/43789708/7761980 – ThingyWotsit

+0

Notez que vous devez vérifier la valeur de retour de chacun des appels 'fgets()'. –

Répondre

6

Le problème est que le tableau second_line est déclarée comme ayant seulement deux éléments.

char second_line[2]; 

Ainsi, après cet appel

fgets(second_line, 2, stdin); 

il ne peut pas accueillir le nouveau caractère de la ligne qui sera encore dans la mémoire tampon d'entrée. Et le premier appel de fgets lit une chaîne vide en raison de la présence du nouveau caractère de ligne dans le tampon d'entrée.

Au moins, vous devriez écrire

char second_line[3]; 

//... 

fgets(second_line, sizeof(second_line), stdin); 

prendre en compte qu'en général cette approche pour supprimer le caractère de nouvelle ligne à partir d'une chaîne est mauvaise

first_line[strlen(first_line)-1] = '\0'; 

, car il ne faut pas que la chaîne contient en effet un nouveau caractère de ligne.

écrire lieu

first_line[ strcspn(first_line, "\n") ] = '\0'; 
0

La deuxième ligne est en fait un caractère dans ce cas. Il y a fgetc() en C qui prend un caractère. Cela peut être utilisé à la place de fgets() dans ce cas. Outre le problème avec fgets() pour la deuxième ligne, il y a un problème avec l'instruction scanf ("% d",). Un espace après spécificateur de format provoque un comportement auquel vous ne vous attendiez pas. De même, le caractère de retour à la ligne entré après la saisie d'une valeur numérique provoque également un comportement d'invite de saut. Cela peut ne pas être la meilleure solution, mais le code suivant résout ce comportement d'invite de saut. Il y a des instructions fgets (caGarbage, sizeof caGarbage, stdin) après scanf() et fgetc(). Cette instruction consomme un caractère de retour à la ligne et résout ainsi ce comportement d'invite de saut.

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

int 
main(void) 
{ 
    char first_line[1000]; 
    char cC; 
    char caGarbage[50]; 
    int i,n,j,k; 
    int count=0,flag=0; 

    printf("Enter count:"); 
    scanf("%d",&k); 
    fgets(caGarbage, sizeof caGarbage, stdin);//Consumes newline character. 

    for(int m=0; m<k; m++) 
    { 
     printf("Insert first line:"); 
     fgets(first_line, 1000, stdin); 

     printf("Insert a character:"); 
     cC = fgetc(stdin); 

     fgets(caGarbage, sizeof caGarbage, stdin); //Consumes newline character 

     for(i=0; i<strlen(first_line); i++) 
     { 
      if(cC == first_line[i]) 
      { 
       flag=1; 
       count++; 
      } 
     } 

     first_line[strcspn(first_line, "\n")] = '\0'; 

     if(flag==1) 
      printf("Occurrence of '%c' in %s = %d",cC,first_line,count); 
     else 
      printf("%c isn't present",cC); 

     printf("\n"); 

     count=0; 
     flag=0; 
    } 

    return 0; 
} 
+0

Pouvez-vous dire plus de détails s'il vous plaît? Combien d'espace/nouvelle ligne pris par scanf ("% d", & k) et cC = fgetc (stdin)? –

+0

Puisque k est un nombre entier, il faudra prendre une valeur numérique, dans la limite de max et min entier. fgetc() prend juste un caractère. Dans les deux cas, le caractère newline est envoyé au tampon d'entrée. Le caractère de nouvelle ligne du beurre d'entrée est reporté sur la déclaration d'entrée suivante. –

+1

pourquoi pas pris ici fgets (caGarbage, sizeof caGarbage, stdin); après fgets (first_line, 1000, stdin); consommer le caractère de nouvelle ligne? @Nguai –

0

Vous ne comprenez pas les détails sur scanf() et fgets() lorsque vous entrez une série ombles à partir du clavier, ces caractères ont été enregistrés dans le inputbuf pas à votre processus. Lorsque vous entrez [Entrée], les caractères dans l'inputbuf ont été envoyés à votre processus (le premier est scanf(), le second est fgets()), scanf() peut choisir les nombres, la clé espace de l'inputbuf. mais il ignore l'entrée et l'a arrêté, donc le '\ n' était toujours dans l'inputbuf mais fgets() non. fgets() récupère le caractère any dans l'inputbuf, inclut '' et '\ n' (il s'arrête tout en obtenant un '\ n').
La différence entre scanf() et fgets() était gênante quand vous les utilisiez en même temps.