Quelle est la façon la plus simple d'obtenir la saisie de l'utilisateur en C?
Il semble y avoir BEAUCOUP de façons que vous pouvez obtenir la saisie de l'utilisateur dans C.
Quelle est la manière la plus simple qui nécessite peu de code?
Fondamentalement, j'ai besoin d'afficher cette:
Enter a file name: apple.text
Essentiellement, j'ai besoin de demander à l'utilisateur un nom de fichier. J'ai donc besoin de quelque chose qui obtient juste qu'un mot que l'utilisateur sera saisie.
- Possible en double stackoverflow.com/questions/314401/...
Vous devez vous connecter pour publier un commentaire.
Le plus simple "correct" moyen est probablement celui-ci, pris de Bjarne Stroustrup du papier L'Apprentissage De C++ Standard Comme Un Nouveau Langage.
(Note: j'ai changé de Bjarne du code pour vérifier
isspace()
au lieu de juste la fin de la ligne. Aussi, en raison de @matejkramny commentaire, à utiliserwhile(1)
au lieu dewhile(true)
...et tant que nous sommes d'être hérétique assez pour modifier de Stroustrup code, je l'ai remplacé en C89 commentaires au lieu de C++ de style trop. :-P)Qui couvre:
Sont il y a plus simple, mais cassé solutions qui peuvent même courir un peu plus vite? Absolument!!
Si vous utilisez scanf dans une mémoire tampon avec aucune limite sur la taille de lecture, puis votre entrée dépasse la taille de la mémoire tampon, il va créer un trou de sécurité et/ou de crash.
Limitation de la taille de la lecture, par exemple, que 100 caractères d'un nom de fichier peut sembler mieux que de s'écraser. Mais il peut être pire; par exemple si l'utilisateur voulu
(...)/dir/foo/bar.txt
, mais vous finissez par une interprétation erronée de leur entrée et de l'écrasement d'un fichier appelébar.t
qui, peut-être qu'ils s'en souciait.Il est préférable d'avoir de bonnes habitudes précoce dans le traitement de ces questions. Mon avis est que si vos besoins en matière de justifier quelque chose de plus proche du métal et de la "C-like", c'est bien la peine d'envisager de passer à C++. Il a été conçu pour gérer précisément ces préoccupations--avec des techniques qui sont robuste et extensible, mais toujours de bons résultats.
/* REVIEW: input correctness, see http://stackoverflow.com/questions/7831755/what-is-the-simplest-way-of-getting-user-input-in-c/ */
Il montre que vous faites votre recherche, ce qui maintient le lien pour une lecture ultérieure. Plus personne débogage d'une base de code qui est d'obtenir un mystère crash peuvent avoir leur attention attirée--voir non seulement l'avertissement, mais un pointeur vers une discussion de la solution correcte.bool
dans cette réponse. La première boucle saute principaux espaces. Merci de lire Apprentissage du C++ Standard, comme un Nouveau Langage si vous souhaitez que ce code a expliqué, car il couvre cet exemple en C et C++ et d'autres.while(true)
qui mon compilateur gémit sur. Je comprends les choses mais maintenant, merci 🙂while(1)
à la place.malloc
etrealloc
ne sont pas allouer assez de mémoire. Il devrait êtremalloc(max * sizeof(char))
pas? En outre, le C ne se soucie pas quemalloc
retournevoid*
de sorte que la conversion implicite n'est pas nécessaire.(char*)
cast n'étant pas nécessaire, il n'est pas mal pour l'avoir...et si quelqu'un est dans l'habitude d'écrire à la fois le C et le C++ code, puis les mettre dans de tels jette rend plus facile si on a souvent des commutateurs entre les langues, ou est l'écriture de code dans le (très gros) sous-ensemble de C qui peut aussi être compilé correctement avec C++.EOF
peut être causée par erreur. POSIX spécifie erreurs suivantes:EAGAIN
,EBADF
,EINTR
,EIO
,EOVERFLOW
,ENOMEM
etENXIO
. Leferror()
oufeof()
les fonctions doivent être utilisées pour faire la distinction entre une erreur et une fin-de-fichier d'état.scanf
semble à travailler dans un non-hostile de l'environnement. En d'autres termes, vous êtes un simple programme utilitaire pour vous-même.BUFSIZ généralement dépasse de loin les limites de taille d'UNIX, les noms de chemins.
Si vous avez besoin d'accumuler des données dans un programme qui pourraient être la cible de dépassement de la mémoire tampon, vous pourriez avoir besoin un peu plus.
C++
puis ಠ_ಠ. Utilisationscanf
en Cvous devez écrire votre propre fgets() fonction wrapper qui lit une ligne de l'entrée dans un tampon d'une taille donnée, et qui supprime le saut de ligne char que fgets() lit aussi. vous pouvez également revenir à un statut de savoir si ou non l'ensemble de la ligne a été en mesure d'entrer dans le tampon (ie. est le saut de ligne à la fin de la mémoire tampon). vous ne devriez jamais vraiment utiliser scanf ou obtient, sauf si vous voulez les débordements.
EDIT: je pensais pourraient fournir une base de code:
scanf
a la limite de caractères, tels quescanf("%99s", mySize100Buffer);
. Mais à la différence defgets
la limite est spécifiée par une chaîne de chiffres, de sorte que la capture de la BUFSIZE-1 relation implique la génération d'une chaîne de format personnalisée. Peu pratique...Utiliser ce code simple