Ceci est pour une tâche de devoir pour trier certaines chaînes données. Je demande à l'utilisateur le nombre de chaînes qu'il souhaite trier avec scanf
, en allouant un tableau basé sur ce nombre, puis en obtenant les chaînes elles-mêmes avec fgets
.Problème avec scanf et fgets
Tout fonctionne correctement si le nombre de chaînes est codé en dur, mais l'ajout de scanf
permet à l'utilisateur de décider de tout vider. Voici le code:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 20 // Maximum string length.
int main(void)
{
int index, numStrings = 0;
char **stringArray;
printf("Input the number of strings that you'd like to sort: ");
assert(scanf("%d", &numStrings) == 1);
stringArray = (char **)malloc(numStrings * sizeof(char *));
for (index = 0; index < numStrings; index++)
{
stringArray[index] = (char *)malloc(LENGTH * sizeof(char));
assert(stringArray[index] != NULL);
printf("Input string: ");
assert(fgets(stringArray[index], LENGTH, stdin) != NULL);
}
// Sort strings, free allocated memory.
return 0;
}
Et voici ce que la console ressemble:
Input the number of strings that you'd like to sort: 3 Input string: Input string: foo Input string: bar
Il saute sur la première itération de la boucle, ce qui entraîne une chaîne vide au début du tableau. Ma question est la suivante: pourquoi fait-elle cela et comment puis-je y remédier?
Voici ce que la console regarde avec la chaîne de format "%d\n"
passé à scanf
:
Input the number of strings that you'd like to sort: 3 foo Input string: Input string: bar Input string: baz
Donc, je peux entrer toutes les chaînes, mais la première invite pour une chaîne est au mauvais endroit .
N'affirmez pas() 'sur des fonctions dont on peut raisonnablement penser qu'elles échoueront, telles que des fonctions d'entrée qui lisent l'entrée de l'utilisateur. C'est mieux que d'ignorer l'erreur; ce n'est pas aussi bon que de gérer correctement l'erreur. –
@Jonathan Merci pour le conseil. – gdejohn