Comment prendre les ints de l'utilisateur en utilisant fgets en C?
Je suis un débutant en C. je suis en train d'écrire un programme qui calcule le volume basé sur la saisie de l'utilisateur de 3 nombres entiers à l'aide fgets()
, et j'ai du mal à comprendre pourquoi mon code ne fonctionne pas.
#include <stdio.h>
#include <stdlib.h>
int volumn(int a, int b, int c);
int main(int argc, char* argv[]){
char* height, width, depth;
fgets(&height, 10, stdin);
fgets(&width, 10, stdin);
fgets(&depth, 10, stdin);
printf("\nThe volumn is %d\n", volumn(atoi(&height), atoi(&width), atoi(&depth)));
return 0;
}
int volumn(int a, int b, int c){
return a * b * c;
}
MODIFIER: j'obtiens les erreurs suivantes/avertissements lorsque j'exécute le code ci-dessus:
goodbyeworld.c:8:11: warning: incompatible pointer types passing 'char **' to
parameter of type 'char *'; remove & [-Wincompatible-pointer-types]
fgets(&height, 10, stdin);
^~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/stdio.h:238:30: note:
passing argument to parameter here
char *fgets(char * __restrict, int, FILE *);
^
goodbyeworld.c:12:48: warning: incompatible pointer types passing 'char **' to
parameter of type 'const char *'; remove & [-Wincompatible-pointer-types]
printf("\nThe volumn is %d\n", volumn(atoi(&height), atoi(&width), a...
^~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/stdlib.h:132:23: note:
passing argument to parameter here
int atoi(const char *);
^
2 warnings generated.
- Bonjour et bienvenue à Débordement de Pile! Pourriez-vous être un peu plus précis sur la façon dont il ne fonctionne pas? Est-il de la compilation? Ne vous obtenez des messages d'erreur? Si il fonctionne, ce qui se fait lorsqu'il s'exécute? Merci d'éditer votre question.
- Toujours, lors de la compilation, de permettre à toutes les mises en garde (pour gcc, à une utilisation minimale:
-Wall -Wextra -pedantic
) fixer ensuite les mises en garde. Avec la publication de code, vous voyez deux mises en garde: 1) unused variable 'argc' 2) unused variable 'argv [] ğ, ainsi que les mises en garde vous voit déjà.
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, une définition comme
faire
height
un pointeur verschar
et le reste deuxchar
s.Ensuite (pas la plus pertinente ici, mais en général, important), Vous n'avez pas à allouer de la mémoire de pointeurs que vous souhaitez utiliser (le cas échéant).
Si vous avez une entrée fixe de longueur décidé que
10
, vous pouvez simplement faire tous les trois variables sous forme de tableau sna utiliser le noms directement, commeet puis
enfin, pensez à utiliser
strtol()
suratoi()
pour une meilleure gestion des erreurs.&height
, le tout est mauvais, de toute façon. 🙂atoi(height)
pas de travail??Vous ne devriez pas. À l'aide de
atoi
pour convertir les données d'entrée pour des entiers quand vous pouvez obtenir l'entrée comme entiers est inutile. Ce que vous cherchez estscanf
.Votre code devrait ressembler à ceci...
scanf()
de toute utilisation dans le monde réel interactive input (et je suppose que c'est ce que l'OP veut faire ici)fgets
est plus "interactif" quescanf
fgets()
, vous pouvez réagir sur inattendue d'entrée correctement, quelque chose qui arrive assez souvent dans le cas interactives.fgets
est mieux. Obtenez de l'entrée, et faire ce que vous voulez valider après. Avecscanf
vous pouvez au moins de spécifier quel type de données que vous êtes enceinte, rendant la validation beaucoup plus simple.strtol()
comme suggéré dans l'autre réponse.%s
ensuite. En outre, les conversions de rajouter du temps d'exécution, et la conversion de quelque chose comme "j'aimerais qu'il soit de 10" avecstrtol
ne serait pas vous donner ce que vous attendez de toute façon, tout le%d
avecscanf
permet à l'échec et invite de nouveau.%s
EST une conversion, bien sûr, cela prend du temps, et c'est tout à fait inutile quand vous le voulez rien d'autre que cette chaîne.%s
vous donne plus ou moins le même comportement quefgets
, moins le retour à la ligne forcé. Et non,%s
n'est pas une conversion, c'est plus d'un type de case,scanf
échoue si l'entrée ne correspond pas aux donneurs d'ordre. Avecfgets
, vous devez obtenir de la chaîne, qui est une action, puis vous devez le convertir, ce qui est une autre action qui peut ou ne peut pas jeter une erreur, car l'entrée peut ou peut ne pas être une valeur convertible pour une longue.%10s
était implicite par mon utilisation de%10d
dans ma réponse.scanf(3)
. Et non, une opération n'est pas plus efficace, tout simplement parce que vous utilisez une grande bibliothèque de fonctions avec des tonnes de cloches et de sifflets au lieu de 2, beaucoup plus simples que même vous donner beaucoup plus de contrôle. Je repose mon cas,scanf()
est une mauvaise idée, au moins interactif d'entrée.fgets
nécessite au moins deux actions, dont l'une est une conversion de type explicite qui le programmeur doit prendre séparé de soins à contre-vérifier les erreurs, ce qui signifie que même plus de travail et plus de code, plus lent et plus de ballonnements. Alors quescanf
, avec ou sans une conversion de type (car il ne permet pas toujours de faire une conversion), tout cela simultanément, la simplification de tout, sans rien sacrifier. Vous avez échoué à montrer commentfgets
est mieux pour "l'interactivité", ou, plus généralement, de mieux de toute autre manière.fgets
etstrtol
mélanger.en C, le nom d'un tableau se dégrade à un pointeur vers la première adresse de la table,
Cependant, les dimensions sont déjà (seulement) des pointeurs qui pointent vers rien.
Le code doit effectivement avoir leur point de mémoire allouée.
En règle générale, cela se ferait via un code similaire:
- Je utiliser 20 au lieu de 10 car un int peut être 13 caractères signe plus en plus newline plus NUL byte et 20 laisse un peu de place supplémentaire.
Le premier paramètre à fgets() est un pointeur vers la mémoire tampon d'entrée et de "hauteur", etc, sont définis comme des pointeurs, donc pas besoin d'une autre " &"
Cependant, l'utilisation de malloc() ajoute également l'obligation de transmettre chacun des trois indicateurs de free() avant de quitter le programme.
se souvenir qu'un int (sur un système 32 bits) peut gérer +/-2gig I. E. 10 chiffres+signe+newline+NUL est un (selon le système d'exploitation) 13 ou 14 caractères.
Suggèrent, utilisation:
Simple solution de votre problème.