fscanf problème avec la lecture en Chaîne
Je suis en train de lire dans un .fichier txt. Je suis en utilisant fscanf pour obtenir les données comme il est formaté.
La ligne je vais avoir des problèmes est: est-ce
result = fscanf(fp, "%s", ap->name);
C'est bien jusqu'à ce que j'ai un nom avec un espace par exemple: St Ives
J'ai donc l'utiliser pour lire dans l'espace blanc:
result = fscanf(fp, "%[^\n]s", ap->name);
Cependant, lorsque j'essaie de lire dans le premier nom (sans espace), il ne fonctionne tout simplement pas et bousille les autres fscanf.
Mais j'utilise le [^\n], il fonctionne très bien dans un autre fichier que j'utilise. Pas sûr de ce qui se passe.
Si j'utilise fgets à la place de la fscanf ci-dessus j'ai "\n" dans la variable.
Edit//
Ok, donc si j'utilise:
result = fscanf(fp, "%s", ap->name);
result = fscanf(fp, "%[^\n]s", ap->name);
Cela me permet de lire dans une chaîne de caractères sans espace blanc. Mais Quand je reçois un "nom" avec un espace qui ne fonctionne pas.
- Est-il possible que vous avez un supplément de caractère de saut de ligne dans votre fichier?
Vous devez vous connecter pour publier un commentaire.
Un problème avec ce:
est que vous avez un supplément de
s
à la fin de votre spécificateur de format. L'ensemble du spécificateur de format devrait être%[^\n]
, qui dit "lu dans une chaîne de caractères qui se compose des caractères qui ne sont pas des retours à la ligne". L'extras
ne fait pas partie du spécificateur de format, il est donc interprété comme un littéral: "lire le caractère suivant à partir de l'entrée; si c'est un "s", continuer, sinon à l'échec".L'extra
s
n'a pas vraiment vous faire du mal, cependant. Vous savez exactement ce que le caractère suivant de l'entrée: un retour à la ligne. Il ne correspond pas, et de traitement des données s'arrête là, mais il n'a pas vraiment d'importance, puisque c'est la fin de votre spécificateur de format. Cela causerait des problèmes, même si, si vous avez eu d'autres spécificateurs de format après celui-ci, dans la même chaîne de format.Le vrai problème, c'est que vous n'êtes pas la consommation de la nouvelle ligne: vous êtes à la seule lecture de tous les personnages jusqu'à la ligne, mais pas le retour à la ligne elle-même. Pour corriger cela, vous devez faire ceci:
La
%*c
spécificateur dit de lire un caractère, (c
), mais ne pas l'affecter à une variable (*
). Si vous avez omis la*
, vous auriez à passerfscanf()
un autre paramètre contenant un pointeur vers un caractère (unchar*
), puis stocker le caractère, qu'il lire dans.Vous pouvez également utiliser
%[^\n]\n
, mais qui aurait également lire dans n'importe quel espace qui a suivi le retour à la ligne, ce qui peut ne pas être ce que vous voulez. Lorsquefscanf
trouve des espaces dans son spécificateur de format (un espace, saut de ligne ou un onglet), il consomme autant d'espace que possible (c'est à dire que vous pouvez penser de la consommation de la plus longue chaîne qui correspond à l'expression régulière[ \t\n]*
).Enfin, vous devez également spécifier une longueur maximale pour éviter les dépassements de la mémoire tampon. Vous pouvez le faire en plaçant la longueur de tampon entre les
%
et la[
. Par exemple, siap->name
est une mémoire tampon de 256 caractères, vous devriez faire ceci:Cela fonctionne très bien pour allouée statiquement des tableaux; malheureusement, si le tableau est dyamically de taille au moment de l'exécution, il n'est pas facile de moyen de passer la taille de la mémoire tampon pour
fscanf
. Vous aurez à créer la chaîne de format avecsprintf
, par exemple:Jumm a écrit:
Qui est de loin le plus facile à résoudre alors, allez avec elle:
Je ne suis pas sûr de savoir comment vous dire [^\n] est suppose de travailler. [] est un modificateur qui dit "accepter un caractère sauf l'un des personnages qui est à l'intérieur de ce bloc". Le
^
inverse la condition. %s avec fscanf ne lit jusqu'à ce qu'il tombe sur un délimiteur. Pour les chaînes de caractères avec des espaces et des retours à la ligne dans les, utiliser une combinaison de fgets et sscanf au lieu de cela, et de spécifier une restriction sur la longueur.Il n'y a pas une telle chose comme je comprends que vous essayez d'impliquer une expression régulière dans le
fscanf
fonction qui n'existe pas, pas que, à ma connaissance, je n'ai vu nulle part - de m'éclairer sur ce.Le spécificateur de format pour la lecture d'une chaîne de caractères est
%s
, il pourrait être que vous avez besoin de le faire de cette façon,%s\n
qui va ramasser le retour à la ligne.Mais bon sang, ne pas utiliser le standard de l'ancien
gets
la famille de fonctionscomme spécifié par Clifford réponse ci-dessuscar c'est là que les dépassements de mémoire tampon se produire et a été utilisé dans un infâme ver des années 1990 - le Ver Morris, plus précisément dans lafingerd
démon, que l'habitude d'appelergets
qui a provoqué le chaos. Heureusement, maintenant, qui a maintenant été corrigé. Et en outre, beaucoup de programmeurs ont été forés dans la mentalité de ne pas utiliser la fonction.Même Microsoft a adopté une version safe de
gets
famille de fonctions, qui spécifie un paramètre pour indiquer la longueur de la mémoire tampon à la place.MODIFIER
Mon mal - je ne savais pas que Clifford, en effet, a précisé la longueur maximum pour l'entrée...Oups! Désolé! Clifford réponse est bonne! Donc +1 pour Clifford réponse.
Merci Neil pour souligner mon erreur...
Espère que cette aide,
Meilleures salutations,
Tom.
J'ai trouvé le problème.
Comme Paul Tomblin dit, j'ai eu un supplément de caractère de nouvelle ligne dans le champ ci-dessus. Donc, en utilisant ce tommieb75 dit que j'ai utilisé:
Et ce fixe!
Merci pour votre aide.
s
n'a pas de sens ici.%[^\n]
déjà demande pour tous les personnages, mais d'une nouvelle ligne.