Intégration QT : pb avec sscanf [Résolu]

Signaler
Messages postés
131
Date d'inscription
samedi 6 janvier 2007
Statut
Membre
Dernière intervention
4 janvier 2011
-
Messages postés
131
Date d'inscription
samedi 6 janvier 2007
Statut
Membre
Dernière intervention
4 janvier 2011
-
Bonsoir à tous !

Un rapide exposé de mon travail, j'ai un projet en openGL qui tourne nickel (sous linux) et je souhaite l'intégrer dans une qglwidget pour une interface QT. Après nombreuses batailles j'arrive à compiler et tout, mais mes pièces ne s'affichent plus. Mes pièces sont des fichiers .obj que je charge dans un loader perso.
Le problème, depuis l'intégration QT, la lecture de ces fichiers ne tourne plus correctement...

Code (épurée):
float a, b, c;
char oneline[255];
while( readstr(filein,oneline) != 0)
{
printf("oneline : %s", oneline);
sscanf(oneline, "%s %f %f %f", buftmp, &a, &b, &c);
printf("scanf => %s %f %f %f\n\n", buftmp, a, b, c);
}

Et en sortie :
oneline : vn 0.831446 0.000000 -0.555559
scanf => vn 0,000000 0,000000 0,000000

Alors certes je pourrais faire un découpage différent mais vu l'avancement du projet, je préfèrerais comprendre l'erreur et patcher ça rapidement.
Je rappel que ces lignes fonctionnent sans l'interface QT, j'ai testé de passer les variables a, b, c en double (en vain).

Merci de votre attention
Je suis tout ouïe à vos suggestions

Bonne soirée à tous

7 réponses

Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
mais j'avoue que ça ne satisfait pas ma curiosité sur mon précédent résultat avec sscanf.

Pour moi, tu as fait les choses correctement, et je ne vois pas pourquoi ça déconnerais. Reste que le mélange C et C++ (plus que QT), pourrait poser problème, mais je ne saurais te l'expliquer.

Pour d'autre cas, il ne fonctionne pas comme je l'aurais pensé :
ex : f 191/191/191 190/190/190 222/222/222 223/223/223

La ligne suivante ne me renvoi de valeurs correcte que pour a
iss >> buftmp >> a >> b >> c >> d >> e >> f >> g >> h >> i >> j >> k >> l;

N'oublie pas que std::istringstream prend comme délimiteur par défaut tout ce qui est dans isspace. Donc il faut que tu lui dises que "/" est délimiteur aussi.

Le même example, avec délimiteur:
#include 
#include <sstream>

int main(void)
{
  float a, b, c;
  char oneline[256] = "vn 0.831446/0.000000/-0.555559";
  std::string buftmp;
  char delim;

  std::cout << "oneline : " << oneline << std::endl;
  std::istringstream iss(oneline);
  iss >> buftmp >> a >> delim >> b >> delim >> c;
  std::cout << "\n\nscanf => "
    << buftmp << " "
    << a << " "
    << b << " "
    << c << std::endl;

  return 0;
}
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
J'ai essayé ceci, en C et C++ et tout semble fonctionner. QT n'est qu'un framework, et n'a normalement pas d'incidence sur le reste.

#include <stdio.h>

int main(void)
{
  float a, b, c;
  char oneline[256] = "vn 0.831446 0.000000 -0.555559";
  char buftmp[256] = {0};

  printf("oneline : %s", oneline);
  sscanf(oneline, "%s %f %f %f", buftmp, &a, &b, &c);
  printf("\n\nscanf => %s %f %f %f\n\n", buftmp, a, b, c);

  return 0;
}


As-tu essayé de faire du C++ au lieu de faire du C ?
Par exemple:
#include 
#include <sstream>

int main(void)
{
  float a, b, c;
  char oneline[256] = "vn 0.831446 0.000000 -0.555559";
  std::string buftmp;

  std::cout << "oneline : " << oneline << std::endl;
  std::istringstream iss(oneline);
  iss >> buftmp >> a >> b >> c;
  std::cout << "\n\nscanf => "
    << buftmp << " "
    << a << " "
    << b << " "
    << c << std::endl;

  return 0;
}
Messages postés
131
Date d'inscription
samedi 6 janvier 2007
Statut
Membre
Dernière intervention
4 janvier 2011
2
Merci CptPingu.

Alors oui en effet, istringstream fonctionne bien, et je sens que je vais tout re-coder avec ça... mais j'avoue que ça ne satisfait pas ma curiosité sur mon précédent résultat avec sscanf.
QT n'est qu'un framework, mais essayez de compiler un projet classique avec QT et vous risquez de voir certaines erreurs que g++ ne me signalé pas. Alors oui, je sais que le qmake ne gènerera qu'un Makefile qui utilise g++/gcc. Mais, même si je n'ai pas envie de trop fourrer mon nez dans des Makefile auto-généré, il s'avère que les résultats des compilations diffèrent...
Et selon mon exemple, le programme ne s'exécute pas de la même manière.

Donc pour résumé, merci beaucoup pour ton aide, je reste à l'écoute pour comprendre en quoi le sscanf "déconne" dans de telles circonstances.
Messages postés
131
Date d'inscription
samedi 6 janvier 2007
Statut
Membre
Dernière intervention
4 janvier 2011
2
Après avoir repassé tout mon code avec des istringstream ... j'ai la surprise du siècle (de mon incompétence surtout)

Dans certains cas, istringstream fonctionne correctement :
ex : vn 0.831446 0.000000 -0.555559

Pour d'autre cas, il ne fonctionne pas comme je l'aurais pensé :
ex : f 191/191/191 190/190/190 222/222/222 223/223/223

La ligne suivante ne me renvoi de valeurs correcte que pour a
iss >> buftmp >> a >> b >> c >> d >> e >> f >> g >> h >> i >> j >> k >> l;

La ligne suivante fonctionne correctement :
sscanf(oneline, "%s %f/%f/%f %f/%f/%f %f/%f/%f %f/%f/%f", buftmp, &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l);

Alors soit je perd la boule, soit j'utilise mal istringstream lors du parsage où les délimiteurs donc des "/".
En espérant ne pas perdre la boule...
Merci pour votre attention
Messages postés
131
Date d'inscription
samedi 6 janvier 2007
Statut
Membre
Dernière intervention
4 janvier 2011
2
Excellent, j'ai plus qu'a tester ça. Moi qui pensait devoir parser en partie ma chaine, je suis ravi de voir que istringstream est intelligent pour un problème comme ça :D
Merci beaucoup CptPingu
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Excellent, j'ai plus qu'a tester ça. Moi qui pensait devoir parser en partie ma chaine, je suis ravi de voir que istringstream est intelligent pour un problème comme ça :D

Attention tout de même, ce n'est pas une propriété de std::istringstream, mais un bon gros hack !
En effet, "delim" étant un caractère, std::instringstream va le remplir avec '/', comme si on le lui demandait.
Si on avait eu ça: "vn 0.831446/0.000000@-0.555559", ça aurait aussi fonctionner !

Normalement, la méthode propre pour faire cela, est en passant par un std:getline auquel on donne la liste des délimiteurs.
Vu que tu cherches juste à faire fonctionner ton truc, je t'ai donné une méthode rapide, mais ce n'est pas la plus robuste et propre :p
Messages postés
131
Date d'inscription
samedi 6 janvier 2007
Statut
Membre
Dernière intervention
4 janvier 2011
2
Pour la robustesse, ça pourra toujours être apporter plus tard. Pour le côté propre, bien sur je pourrais tester que la caractère de séparation soit bien '/' ... mais les fichiers .obj que je charge ont une référence plutôt précise, et à laquel je souhaite coller. Donc pour ce cas là, ce sera largement suffisant.
Et par simple curiosité, pour ton explication :
Si on avait eu ça: "vn 0.831446/0.000000@-0.555559", ça aurait aussi fonctionner !

Je me demandais si j'avais eu : "vn 0.831446/0.000000-0.555559" est ce que cela aurait fonctionner ?
Je vais tester ça dessuite.
En tout cas MERCI ;)