Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

string path et '?'


Sujet :

SL & STL C++

  1. #1
    Futur Membre du Club
    string path et '?'
    Bonjour,

    Je me suis fait un singleton qui récupère tout un lot de constantes que j'ai dans une fichier de config.

    Ca fonctionne plutot bien tant que je ne fais qu'afficher mes string récupérés. Sauf que j'ai des string qui sont des path et qui me servent entre autre a creer un fichier xml (j'utilise tinyxml).
    Sauf que le path que je recupere fait peter une erreur sur la creation du fichier xml.

    Du coup j'ai crée a la main un fichier portant le nom de mon xml et là... en faisant un ll (je suis sous linux) dans le repertoire ,je m'appercois que mon fichier s'appelle:

    monnom.xml?

    Avec un '?' a la fin!! (un cout sur le path m'affiche juste monnom.xml)

    __________________________________________________________________________________________________________

    Du coup j'ai tenté diverses choses genre concaténer "[", "monnom.xml" et "]" pour l'afficher avec cout, ca m'affiche:

    ]monnom.xml

    Je suis pas habitué au c++, ni a linux, du coup je sais pas trop ou chercher ><

    Pour info je recupere le path dans le fichier initial comme ca:

    Dans mon singleton qui recupere et met a dispo les data de conf:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    std::ifstream fichier(fichier_conf.c_str(), ios::in);


    un getline puis un split sur la line:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    int conf::Split(vector<std::string>& result, std::string chaine, char separateur)
    {
    	result.clear();
     
    	std::string::size_type stTemp = chaine.find(separateur);
     
    	while(stTemp != std::string::npos)
    	{
    		result.push_back(chaine.substr(0, stTemp));
    		chaine = chaine.substr(stTemp + 1);
    		stTemp = chaine.find(separateur);
    	}
     
    	result.push_back(chaine);
     
    	return result.size();
    }


    et je recupere une constante de mon vecteur comme ca (une methode pour chaque type int/double/bool/string):

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    string conf::GetStringValue(string name)
    {
    	for(int i = 0 ; i < m_ConfValues.size(); i++)
    	{
    		cout<<m_ConfValues[i][0].c_str()<<endl;
    		if(m_ConfValues[i][0] == name)
    		{
    			return m_ConfValues[i][1].c_str();
    		}
    	}
     
    	return "";
    }


    Ailleurs, je tente de faire :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    TiXmlDocument *doc = new TiXmlDocument(nomFichier.c_str());
    	if(!doc->LoadFile()){
    		cerr << "erreur lors du chargement" << endl;
    		cerr << "error #" << doc->ErrorId() << " : " << doc->ErrorDesc() << endl;
    		return false;
    	}


    avec monfichier qui est le retour de GetStringValue. Mais avec un '?' en trop è_é

    Merci si vous avez des pistes

    Inter'

  2. #2
    Expert éminent sénior
    Je n'aime pas trop ce [i][0]. Ca me semble très étrange

    Pourquoi n'utilises-tu pas des map?
    Quelque chose comme map<string, string> et map<string, double>?

    montres nous ta classe complete?

    Par ailleurs, es-tu sur de vouloir en faire un singleton?

    ps: pense à utiliser la balise [code] (le #)
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Futur Membre du Club
    Humm, si je puis me permettre, rien de ce que je pourrais apporter en repondant a tes questions ne me semble pertinent pour mon probleme mais bon...

    La map: j'ai commencé avec un vector<string> pour split mes entrees une a une, j'ai fini avec un vector<vector<string>> pour stocker toutes mes entrees. J'ai pas pris le temps de modifier en map apres coup vu que ca restait fonctionnel.

    Le choix du singleton: bha eux oui c'est necessaire si je veux pas stocker 50 intance d'une classe qui va lire un fichier pour garder en memoire des valeurs de constantes.

    Le reste du code: c'est le code d'un singleton le plus simple au monde et les autres classes GetDoubleValue/Bool/Int, y a t il un reel interet a copier du code qui n'interfere en rien avec mon probleme?

    Le probleme est plus dans une manipulation foireuse des string/Format d'ecriture ou autre specifique au c++ que je ne maitrise pas je pense.
    Est ce que me racuperation de la chaine de caractere dans le fichier d'origine ne genere pas un string qui n'ai pas de caractere de fin ou autre???

    Ma classe est fonctionnelle pour les double/bool et int en utilisant exactement les memes object que pour le string. Sauf que l'utilisation que je fais de mon string n'en permet pas l'exploitation a cause de ce '?' qui cache vraisemblablement un caractere zarb en trop.

  4. #4
    Expert éminent sénior
    Avec tout le code concernant les strings, on verrait mieux.
    Ton problème peut venir à plusieurs moments:

    • mauvais parsage
    • mauvais stockage
    • mauvaise récupération
    • mauvais affichage
    • erreur de la console, qui ne sais pas afficher un caractère bizarre
    • erreur de conversion
    • slicing intempestif de string
    • passage superflu par les const char* (c_str())


    Je ne sais pas si string est std::string ou un typedef sur const char*, mais "cout <<" ne requiert pas d'utiliser c_str()
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Futur Membre du Club
    Bonjour,

    Oui, le cout<< avec le c_str() etait du a un c/c de fleimard sur la variable

    Donc pour le reste:

    conf.h
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #ifndef CONF_H
    #define CONF_H
    #ifndef STRING
    #include <string>
    #include <vector>
    using namespace std;
    #endif
     
    class conf
    {
    public:
    		static conf* GetInstance();
    		std::string GetStringValue(string name);
    		int GetIntValue(string name);
    		double GetDoubleValue(string name);
    		bool GetBoolValue(string name);
     
    private:
    		string fichier_conf;
    		std::vector<std::vector<string> > m_ConfValues;
     
    		conf();
    		~conf();
     
    		static conf* m_Instance;
     
    		void init();
    		int Split(vector<std::string>& vecteur, std::string chaine, char separateur);
    };
    #endif


    conf.cpp
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    #include "conf.h"
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    #include <sstream>
     
    using namespace std ;
     
    conf * conf::m_Instance;
     
    conf* conf::GetInstance()
    {
    	if(!m_Instance)
    	{
    		m_Instance = new conf();
    	}
     
    	return m_Instance;
    }
     
    conf::conf()
    {
    	fichier_conf = "../config/conf.ini";
    	std::cout<<"Creation"<<std::endl;
    	init();
    }
     
    conf::~conf()
    {
    	std::cout<<"Destruction"<<std::endl;
    }
     
    string conf::GetStringValue(string name)
    {
    	for(int i = 0 ; i < m_ConfValues.size(); i++)
    	{
    		cout<<m_ConfValues[i][0]<<endl;
    		if(m_ConfValues[i][0] == name)
    		{
    			return m_ConfValues[i][1];
    		}
    	}
     
    	return "";
    }
     
    int conf::GetIntValue(string name)
    {
    [...]
    }
     
    double conf::GetDoubleValue(string name)
    {
    [...]
    }
     
    bool conf::GetBoolValue(string name)
    {
    [...]
    }
     
    void conf::init()
    {
    	// lire le fichier
    	    std::ifstream fichier(fichier_conf.c_str(), ios::in);  // on ouvre le fichier en lecture
     
    		int count = 0;
            if(fichier)  // si l'ouverture a réussi
            {       
    			// recuperer les couples nom/valeur
    			std::string line;
    			while(getline(fichier, line))
    			{
    			count++;
     
    				if(line != "")
    				{
    					// stocker les valeurs
    					//std::cout<<line<<endl;
    					vector<std::string> result;
    					if(Split(result , line, '=') == 2)
    					{
    						m_ConfValues.push_back(result);
    					}
    					 else
    					{
    						std::ostringstream err;
    						err << "Format de ligne inattendu [" << count << "]" << endl;
    						cerr << err.str();
    					}
    				}
    				else
    				{
    					cerr << "Ligne sans donnée" << endl;
    				}
    			}
                // instructions
    			fichier.close();
            }
            else  // sinon
                    cerr << "Impossible d'ouvrir le fichier !" << endl;
     
    	std::cout<<"FIN INIT"<<endl;
    }
     
    int conf::Split(vector<std::string>& result, std::string chaine, char separateur)
    {
    	result.clear();
     
    	std::string::size_type stTemp = chaine.find(separateur);
     
    	while(stTemp != std::string::npos)
    	{
    		result.push_back(chaine.substr(0, stTemp));
    		chaine = chaine.substr(stTemp + 1);
    		stTemp = chaine.find(separateur);
    	}
     
    	result.push_back(chaine);
     
    	return result.size();
    }


    Dans mon main j'ai :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main(){
     
    	conf* m_ConfValues  = conf::GetInstance();
     
    	std::cout<<"EXTRACTION_FICHIER"<<endl;
    	//extraction du fichier xml contenant le plan de vol ==================================================================
    	vector<Position> waypoints;
    	if(!Position::extractPoints(m_ConfValues->GetStringValue("Chemin_Plan_De_Vol"),waypoints)){
    		cerr << "erreur de lecture de "<< m_ConfValues->GetStringValue("Chemin_Plan_De_Vol") << endl;
    		return 1;
    	}
    [...]
    }


    Avec dans Position.h
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    static bool extractPoints(string s,vector<Position> &waypoints);

    et dans position.cpp
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    bool Position::extractPoints(string nomFichier,vector<Position> &points){
    TiXmlDocument *doc = new TiXmlDocument(nomFichier.c_str());
    	if(!doc->LoadFile()){
    		cerr << "erreur lors du chargement" << endl;
    		cerr << "error #" << doc->ErrorId() << " : " << doc->ErrorDesc() << endl;
    		return false;
    	}


    Et j'ai systématiquement un erreur (dont la description ne s'affiche pas).

    La ligne du fichier conf.ini est celle ci:
    Chemin_Plan_De_Vol=../config/planvol.xml


    Quand je fais, a la place du code precedent, ca fonctionne:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    static bool extractPoints(string s,vector<Position> &waypoints);

    et dans position.cpp
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool Position::extractPoints(string nomFichier,vector<Position> &points){
    nomFichier = "../config/planvol.xml";
    TiXmlDocument *doc = new TiXmlDocument(nomFichier.c_str());
    	if(!doc->LoadFile()){
    		cerr << "erreur lors du chargement" << endl;
    		cerr << "error #" << doc->ErrorId() << " : " << doc->ErrorDesc() << endl;
    		return false;
    	}


    Et en faisant
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::ofstream outfile (nomFichier.c_str());
     
    outfile << "my text here!" << std::endl;
     
    outfile.close();


    j'ai un fichier xml de type text qui se cree, mais un cou pde ll dans le repertoire me montre son nom comme etant
    "nomFichier.xml?"

    D'ou le fait que new TiXmlDocument(nomFichier.c_str()); ne fonctionne pas, le charactere qui se cache derriere le "?" lui posant un probleme.

    J'espere avoir mis suffisement d'info

    Merci

    Inter'

    edit: j'ai resolu mon probleme en faisant un substr sur le dernier char dans ma methode GetStringValue, mais je ne suis que moyennement convaincu ~~ jevais faire avec pour le moment mais a l'occaz si quelqu'un a une explication, je suis preneur.
    Merci