2012-10-09 1 views
0

Donc, je ne peux pas vraiment comprendre pourquoi scanf gâche un [0]. Quand j'imprime le tableau, un [0] est vide et où je veux un [0] il est stocké dans un [1].L'utilisation de scanf avant pour la boucle avec fgets retourne a [0] comme vide

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

int main(int argc, char *argv[]) 
{ 
    char *a[128]; 
    int i; 
    int num; 

    scanf("%d", &num); 

    for (i = 0; i < 2; i++) { 
     a[i] = malloc(50*sizeof(char)); 
     fgets(a[i], 100, stdin); 
    } 

    printf("[0] = %s [1] = %s", a[0], a[1]); 

    return 0; 
} 
+0

Quelle est votre contribution? –

+0

dis que je mets: 1 [entrez] ceci est une chaîne [entrée] – user1455112

Répondre

3

Votre scanf() est pas déconner votre a[0], du moins pas de la manière que vous semblez penser, en corrompant en quelque sorte sa zone de stockage. C'est vraiment un problème avec le mélange de différentes "méthodes" d'entrée.

Qu'est-ce qui se passe réellement avec votre combo scanf/fgets est que le scanf est d'obtenir l'entier, mais pas la lecture de la nouvelle ligne que vous entrez à la fin de ce numéro, de sorte que les premiers fgets choix que vers le haut.

La norme ISO it donc (dans l'ordre indiqué):

entrée de caractères d'espace blanc (tel que spécifié par la fonction de isspace) sont ignorés, à moins que le cahier des charges comprend un [, c, ou n spécificateur.

Un élément d'entrée est lu dans le flux, sauf si la spécification inclut un spécificateur n. Un élément d'entrée est défini comme la plus longue séquence de caractères d'entrée qui ne dépasse pas une largeur de champ spécifiée et qui est ou est un préfixe d'une séquence d'entrée correspondante.

Le premier caractère, le cas échéant, après l'élément d'entrée reste non lu.

Ce premier et dernier paragraphe est important. Le premier signifie que l'espace blanc de début est ignoré, le dernier signifie que les espaces de fin sont laissés dans le flux d'entrée pour être lus plus tard.


Cependant, je vais vous dire ce que peut mess it up (en fonction de la longueur de vos lignes d'entrée), il est le fait que vous allouez de l'espace 50 caractères pour chaque a[i] alors lu jusqu'à 100 caractères dans ça. C'est un comportement indéfini là.


Si vous voulez une solution d'entrée robuste qui gère correctement la taille des tampons, des lignes détecte trop longues, jette les restes de ces lignes et ainsi de suite, voir this answer.

Alternativement, si vous voulez imiter le comportement basé sur la ligne avec la base non-ligne scanf (et vous êtes sûr que vos lignes sont toujours inférieures à 100 octets), vous pouvez modifier:

scanf("%d", &num); 

dans:

char junk[100]; 
scanf ("%d", &num); 
fgets (junk, sizeof (junk), stdin); 

afin qu'il attrape et jette le reste de la ligne.

Et vous devez vous assurer que l'argument de taille maximale à fgets correspond à la quantité de mémoire disponible (par exemple en utilisant sizeof dans le code ci-dessus).

Une autre chose, s'il vous plaît ne pas compliquer le code en multipliant les choses par sizeof(char) - cette valeur est toujours 1 selon la norme.