Comment puis-je lire une entrée de chaîne de longueur inconnue?
Si je ne sais pas combien de temps le mot est, je ne peux pas écrire char m[6];
,
La longueur du mot est peut-être dix ou vingt de long.
Comment puis-je utiliser scanf
pour obtenir l'entrée à partir du clavier?
#include <stdio.h>
int main(void)
{
char m[6];
printf("please input a string with length=5\n");
scanf("%s",&m);
printf("this is the string: %s\n", m);
return 0;
}
veuillez saisir une chaîne de longueur=5
bonjour
c'est la chaîne: bonjour
- utilisez le pointeur de realloc combinaison
- Vous pouvez déposer le
&
dansscanf("%s",&m)
depuism
est déjà un pointeur vers le premier élément dem[]
dans cette expression.
Vous devez vous connecter pour publier un commentaire.
Entrée lors de la sécurisation d'une zone dynamiquement
E. G.
sizeof(char)
? Ugh.char
avecwchar_t
, cette solution fonctionne encore, contrairement à d'autres solutions, qui aurait besoin de plus de bricoler!sizeof(char)
est1
.size
spécifié pour le premier est de 0, car il est un non-sens. Et si nous pouvons le vérifier.sizeof (*str)
. Mais encore, c'est de la paranoïa galopante et une odeur de code.sizeof (*str)
de sorte que vous n'avez même pas à modifier la multiplication lorsque le type de changements.str[len]='\0'; return realloc(str, len);
entraînera la terminaison d'être mis au rebut. Je pense que vous vouliez direstr[len++] = '\0'
.if (len>size)
. Etsizeof(char)
est toujours 1.malloc()
à base de solution) est confrontée au problème de savoir quoi faire quand nous sommes à court de mémoire.main()
besoins d'une gestion d'erreur lorsqueinputString()
retourneNULL
.size_t size = 10
?realloc(NULL, sizeof(char)*size);
le même quemalloc(sizeof(char) * size)
? Quelle est la raison quirealloc
est préféré ici?malloc(sizeof(char) * size)
.realloc
ne peut pas être remplacé parmalloc
. Si vous l'avez modifiée, vous auriez àfree
la mémoire avant.realloc
se charge de toutmalloc
ne l'est pas.realloc(NULL, sizeof(char)*size); the same as malloc(sizeof(char) * size)
realloc(...)
avecmalloc(...)
conduit à le même comportement, alors que c'est faux. Lorsque vousrealloc
avec succès, il libère la mémoire précédent, tandis quemalloc
ne l'est pas. Ils ne sont donc pas interchangeables comme vous l'avez dit.realloc(NULL, sizeof(char)*size); the same as malloc(sizeof(char) * size)
. Je ne dis pas la même chose demalloc
etrealloc
.realloc
avecmalloc
, pas seulement la première. Je suis désolé.realloc
dansinputString
vraiment nécessaire ?inputString()
n'est pas juste de retourstr
? Est-ce gratuit la les octets non utilisés si la longueur de la chaîne entrée stdin est inférieure à la taille (taille initiale)?wwchar_t_t
! Je les utilise tout le temps dans ma pile wchar_tger pour afficher un message d'erreur si la batterie est trop loin diswchar_tged ou a un unwchar_tacteristic wchar_tging courbe. (Les batteries endommagées sont dangereux pour rechar_tge et peut coûter un surwchar_tge à recycler)realloc
échoue dansreturn realloc(str, sizeof(char)*len);
. Cet appel est une perte de temps de toute façon puisque je doute qu'un système a plus fines malloc granularith de 16 octetsAvec les ordinateurs d'aujourd'hui, vous pouvez vous en sortir avec l'allocation de très grandes chaînes de caractères (des centaines de milliers de caractères) alors qu'à peine faire une brèche dans l'ordinateur de l'utilisation de la RAM. Donc, je ne m'inquiéterais pas trop.
Cependant, dans les vieux jours, quand la mémoire est à une prime, la pratique courante était de lire des cordes en morceaux.
fgets
lit jusqu'à un nombre maximum de caractères à partir de l'entrée, mais qui laisse le reste de la mémoire tampon d'entrée intacte, de sorte que vous pouvez lire le reste de celui-ci que vous aimez.dans cet exemple, j'ai lu en morceaux de 200 caractères, mais vous pouvez utiliser n'importe quel morceau de la taille que vous voulez, bien sûr.
Remarque que c'est un exemple simplifié avec aucune vérification d'erreur; dans la vraie vie, vous devrez assurez-vous que l'entrée est OK, vérifier la valeur de retour de
fgets
.Également noter qu'à la fin si le readinput de routine, pas d'octets sont perdues; la chaîne a exactement la taille de la mémoire dont il a besoin.
realloc()
retourNULL
(et, par conséquent, pourreadinput()
retourNULL
).fgets()
, d'autre code peut entrer dans une boucle infinie.J'ai vu qu'un simple façon de lire un arbitrairement long de la chaîne, mais je n'ai jamais utilisé. Je pense qu'il va comme ceci:
La
m
entre%
ets
ditscanf()
à mesure de la chaîne et de l'allouer de la mémoire et de copier la chaîne, et à stocker l'adresse de la mémoire allouée dans l'argument correspondant. Une fois que vous avez fini avec elle, vous avez àfree()
il.Ce n'est pas pris en charge sur chaque mise en œuvre de
scanf()
, si.Comme d'autres l'ont souligné, la solution la plus simple est de définir une limite sur la longueur de l'entrée. Si vous voulez toujours utiliser
scanf()
alors vous pouvez le faire de cette façon:Noter que la taille de
m[]
doit être d'au moins un octet de plus grand que le nombre entre%
ets
.Si la chaîne d'entrée est de plus de 99, puis le reste des personnages attendre à être lu par un autre appel ou par le reste de la chaîne de format transmis à
scanf()
.Généralement
scanf()
n'est pas recommandé pour la manipulation de la saisie de l'utilisateur. Il est préférable d'appliquer à la base de fichiers texte structurés qui ont été créé par une autre application. Même alors, vous devez être conscient que l'entrée peut ne pas être formaté comme il faut que quelqu'un peut avoir interféré avec elle pour essayer de casser votre programme."%ms"
n'est pas la norme C --- c'est probablement l'une extension POSIX ou une extension GNU.Si je peut suggérer une approche plus sûre:
Déclarer un tampon assez grand pour contenir la chaîne:
char user_input[255];
Obtenir la saisie de l'utilisateur dans un sûr façon:
fgets(user_input, 255, stdin);
Un moyen sûr pour obtenir l'entrée, le premier argument un pointeur vers une mémoire tampon dans lequel les données seront stockées, la seconde le maximum d'entrée de la fonction devrait lire, et le troisième est un pointeur sur l'entrée standard - par exemple, lorsque l'entrée utilisateur vient de.
Et en particulier la sécurité vient de la deuxième argument de la limitation de combien sera de lire ce qui empêche les dépassements de la mémoire tampon. Aussi,
fgets
prend soin de null-résiliation du traité de chaîne.Plus d'informations sur cette fonction ici.
EDIT: Si vous avez besoin de faire toute la mise en forme (par exemple convertir une chaîne en nombre), vous pouvez utiliser atoi une fois que vous avez entrée.
fgets(user_input, sizeof user_input, stdin);
est plus sûr.Plus sûr et le plus rapide (doublement de la capacité) version:
sizeof (char)
est redondant;sizeof (char)
est de 1 par définition.prompt
devrait être unconst char *
.malloc
etrealloc
appels d'erreurs.size *= 2
risque de déborder.Prendre un pointeur de caractère pour stocker la chaîne voulue.Si vous avez une idée sur une taille de chaîne puis utiliser la fonction
autre chose que vous pouvez allouer de la mémoire à l'exécution trop l'utilisation de malloc() fonction de manière dynamique, offre mémoire demandée.
Lire directement dans l'espace alloué avec
fgets()
.Une attention particulière est nécessaire de distinguer une réussite en lecture, en fin de fichier, erreur d'entrée et de sortie de la mémoire. La bonne gestion de la mémoire nécessaire sur les expressions du FOLKLORE.
Cette méthode conserve une ligne
'\n'
.Exemple d'utilisation
-fpermissive
, mais une plainte compilateur C pas donner ce message et ce post est marquéC
.Je sais que je suis arrivé après 4 ans et je suis trop en retard, mais je pense que j'ai une autre façon que quelqu'un peut utiliser. J'avais utilisé
getchar()
Fonction comme ceci:-voici l'exemple d'exécution de ce programme:-
j'ai aussi une solution standard d'entrées et de sorties
scanf
devraient être comparées pour le nombre d'éléments que vous lisez, pasEOF