2011-03-11 8 views
2

Je veux lire les nombres flottants (et ints après) d'une ligne que je sors d'un fichier. Quand je le débogue, je peux voir qu'il n'y a pas de problème avec la ligne, mais quand j'essaye de le faire, je suis dans la foutaise. Voici mon code:Confusion à propos de sscanf

while(fgets(line, 1000, file) != EOF) 
    { 
     //Get the first character of the line 
     c = line[0]; 

     if(c == 'v') 
     { 
      sscanf(line, "%f", &v1); 
      printf("%f", v1); 
     } 
    } 

La valeur stockée dans v1 est garbage. Pourquoi cela ne fonctionne-t-il pas, et comment puis-je obtenir des flotteurs et des ints hors de cette ligne?

Répondre

5

Vous » re incluant le premier caractère (qui est 'v') dans l'appel à sscanf, donc l'appel échoue et v1 est laissé intact (avec la poubelle dedans). Essayez ceci:

sscanf(line+1, "%f", &v1); 
+0

Parfait, cela résout mon problème sscanf. Merci! – Jeff

+1

Et, v1 était garbage parce qu'il n'était pas initialisé. Vérifiez si sscanf a réellement initialisé les arguments que vous lui donnez, 'if (sscanf (ligne + 1,"% f ", & v1))! = 1) {// erreur}' – nos

2

Probablement v1 est un flotteur?

Dans ce cas, l'impression d'un flotteur en mémoire comme si elle était une chaîne « c » va être mauvais ..
Vous pourriez vouloir essayer printf("%f",v1);

if(c == 'v') 
    { 
     sscanf(line, "%f", &v1); 

Si la ligne commence par « v » alors vous l'envoyez à scanf et lui demandez de le convertir en float? Vous voulez probablement déplacer un caractère (ou plus si vous avez un autre remplissage) et commencer à lire le flotteur à la ligne [1]?

+0

Haha, merci. Mais c'était juste là pour le débogage de toute façon. Mon vrai problème est que v1 détient des ordures. Une idée de comment je peux réparer ça? – Jeff

+0

En code réel, vous devriez utiliser strtod() si vous l'avez - il peut marquer si la chaîne n'est pas un flottant valide. en regardant le code, vous devez passer le 'v' au début de la ligne et envoyer la ligne [1] à sscanf() –

1

Votre printf devrait ressembler à ceci:

printf("%f\n", v1); 

En outre, vous devriez vérifier la valeur de retour de sscanf pour vérifier si elle est même de trouver et de stockage du flotteur:

if(sscanf(line, "%f", &v1) < 1){ 
    /* didn't read float */ 
}else{ 
    printf("%f\n", v1); 
} 
1

Puisque vous savez lorsque vous exécutez l'sscanf() appel que le premier caractère line est la lettre « v », vous pouvez aussi dire qu'il n'y a aucun moyen que sscanf() peut réussir à convertir ce à double ou float car 'v' ne fait partie d'aucun nombre pointant flottant valide présenté sous forme de chaîne.

Vous devez vérifier la valeur de retour de sscanf(); cela signifierait 0 (pas de conversions réussies), ce qui vous dirait que quelque chose s'est mal passé.

Vous pourriez réussir avec:

if (sscanf(line+1, "%f", &v1) != 1) 
    ...error... 
+0

Merci pour votre réponse, votre explication est très claire. Si j'avais fait quelque chose comme sscanf (ligne, "% s% f", v1) cela aurait-il bien fonctionné? – Jeff

+0

@Jeff: comme écrit, non - 'sscanf()' essayera de copier la chaîne dans le flotteur qui serait horrible. Ce qui pourrait fonctionner est 'sscanf (ligne,"% * s% f ", &v1);' où le très important '*' veut dire 'faire une conversion mais ne l'assigner nulle part'. Sachez que le '% * s' sauter une série de caractères non vierges Si la chaîne d'entrée est 'v 3.1416' (espace après le 'v'), alors cela fonctionnera bien si l'entrée est' v3.1416' ou 'v + 3.1416' (pas d'espace), alors le nombre serait consommé en tant que partie de la chaîne. –

+1

@Jeff - Cela se bloque pour plusieurs raisons. D'abord, vous passez 'v1' au lieu de' & v1'. Deuxièmement, vous spécifiez deux conversions de format mais en ne donnant qu'un seul emplacement pour les mettre. Vous pouvez utiliser 'sscanf (ligne," v% f ", & v1)'. –

Questions connexes