Tableau de string [Résolu]

Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 10 août 2012 à 17:37 - Dernière réponse : cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention
- 13 août 2012 à 15:22
Bonsoir,

Je n'arrive pas a faire un truc tout simple (et ça m'agace mais alors m’agacccccccce)

Je commence a utiliser espace de nom std (qui vas me faire gagné pas mal de temps maintenant que je peut l'utiliser dans mes projets pro, eennffiinn ).

Je cherche à passer un pointeur sur tableau a une sous fonction qui doit dimensionner le tableau, le remplir, et se terminer (avec une valeur de retour pour remonté les erreurs)

Habituellement j'utilisais des char*, je débute avec les string (et wstring).

Je fait donc :
Déclaration :
char DecoupeLigne(const wstring Ligne,const wstring Separateur,int* NombreDeChampsTrouve,wstring** TableauDeStringTrouve)
{
[...]
*TableauDeStringTrouve = (wstring*)malloc(sizeof(wstring*)*NombreDeChampsLut);
for (int Compteur = 0 ; Compteur<NombreDeChampsLut ; Compteur++)
{
(*TableauDeStringTrouve)[Compteur] = new wstring(); //<-- ICI
(*TableauDeStringTrouve)[Compteur] = CourElement->Item;
CourElement = CourElement->Suivant;
}
}

Appel :
wstring Ligne;
wstring* ListeDonnees;
[...]
DecoupeLigne(Ligne,L"\t",&NombreItem,&ListeDonnees);


J'ai une erreur a la compilation sur la ligne noté "ICI" :
Error 1 error C2106: '=' : left operand must be l-value xxx.cpp 120 1 yyy

Ce qui veux dire (sauf erreur de ma part ^^) que je cherche a mettre un pointeur dans une variable...

Je comprend bien l'erreur (l'opérateur "=" est redéfini par la classe string je ne peut donc pas insérer comme ça l'adresse de ma variable dans mon tableau , ce qui me permet de faire la ligne suivante sans "strcpy" ou autre "memcpy" ^^) mais je ne trouve pas de solution pour contourner ça

Comment faire svp ?

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Afficher la suite 

Votre réponse

16 réponses

Meilleure réponse
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 13 août 2012 à 14:44
3
Merci
Je pense que je doit convertir mon "wostringstream" en "basic_istream". Et je trouve pas

Oula, non. Surtout pas. Attention, il n'y a pas d'héritage mais plutôt du gros templating ^^, ce qui n'est pas pareil. Tu ne pourras donc pas faire cette "conversion". Un "std:wostringstream" est en réalité alias pour le type "std::basic_istream<wchar_t>".
Le moteur de templating est la chose la plus puissante du C++, mais aussi la plus complexe à aborder (c'est presque un langage dans le langage).

Néanmoins, ce n'est pas ici ton erreur. Il y en C++, une classe pour lire (std::ifstream), une classe pour écrire (std::ofstream) ou une classe pour faire les deux (std::fstream). Ici tu as indiqué un "std::wofstream" au lieu d'un "std::wifstream".

Voici un exemple fonctionnel:
#include 
#include <fstream>
#include <sstream>
#include <vector>

#include <string>

int main()
{
  std::wifstream file ("test.txt");
  if (file)
  {
    std::wstring line;
    std::vector<std::wstring> datas;
    while (std::getline(file, line))
    {
      std::wstring word;
      std::wistringstream buff(line);
      while (std::getline(buff, word, L'\t'))
datas.push_back(word);
    }
  }

  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question

Merci cptpingu 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de cptpingu
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 10 août 2012 à 17:40
0
Merci
Oups j'ai mit l'erreur IntelliSense dans mon message

L'erreur :
Error 1 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::wstring *' (or there is no acceptable conversion) xxx.cpp 120 1 yyy


Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 10 août 2012 à 18:43
0
Merci
Bonjour.

Tout d'abord, quelques remarques:
- Évite les "using namespace", voir: http://0217021.free.fr/portfolio/axel.berardino/articles/bon-usage-using-namespace
- En C++ on ne fait jamais de malloc/free, on fait du new/delete. (Attention, lors d'un new, il y a bien appel du constructeur à l'initialisation, ce qui n'est pas le cas d'un malloc !)
- Pourquoi ne pas utiliser un std::vector au lieu de faire un tableau C ? (Je verrais bien à la place de "wstring**" un petit "std::vector<std::wstring>&")
- new std::wstring(); => new std::wstring; ! Attention dans le cas d'un new sur constructeur sans parenthèse, il n'y a pas de "()". C'est une subtilité du C++. Si tu mets les parenthèses tu déclares une fonction anonyme qui renvoie un type std::wstring et qui fait un new du résultat. Ça fonctionne, mais c'est moche :).

Pour ton souci, si je ne m'abuse, le type de "(*TableauDeStringTrouve)[Compteur]" c'est "std::wstring" et non "std::wstring*".
C'est tout simplement ça ton problème, non ?

Autre petite chose. Je vois un "CourElement = CourElement->Suivant;", ça ressemble à une liste chaînée. Sache qu'en C++, tu n'as pas besoin de la recoder, tu as déjà les std::list (liste doublement chaînée) et les std::forward_list (liste simplement chaînée).

Enfin, pour parcourir une collection C++, il est préférable d'utiliser des iterators.


Si tout ceci n'est pas clair, je te ferais un petit exemple.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 10:54
0
Merci
Bonjour,

Et tout d'abord merci pour tes conseils .

Pour répondre aux pourquoi, je suis de formation C, et je doit reconnaitre que je ne connais pas encore les outils disponible en C++ .

Tout me semble claire mis a part les "iterators" ?

Je m'applique déjà à recorder tout ça en suivant tes conseils et je posterais ici.

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 11:36
0
Merci
Arf j'ai des soucis :

(Pour la petite histoire, je travail dans un projet anciennement C qui évolue maintenant vers du C++. Néanmoins la majeur partie du code n'a pas encore évolué, un collègue c'est occupé des quelques modifications indispensable pour que le projet fonctionne sans erreur. Maintenant je cherche a utiliser les outils a ma disposition ^^)

J'ai lut ton lien concernant les "using namespace" :
"using namespace" = >

J'ai une erreur sur l'utilisation des listes :
Error 1 error C2039: 'forward_list' : is not a member of 'std' xxxxxx.cpp 75 1 yyyyyyyy

Idem sur le vector :
Error 1 error C2039: 'vector' : is not a member of 'std' xxxxxx.cpp 62 1 yyyyyyyy

Des lib sont ignorées, peut être la cause de l'erreur ??? :
Param "Ignore Specific Default Libraries" :
libc.lib;%(IgnoreSpecificDefaultLibraries)

A part cette configuration je ne voie rien qui m'attire l’œil niveau configuration

PS :
Mon code actuel (qui est fonctionnel, le "new" tout bêtement, j'aurais dû y penser tout seul ) :
char DecoupeLigne(const std::wstring Ligne,const std::wstring Separateur,int* NombreDeChampsTrouve,std::wstring** TableauDeStringTrouve)
{
[...]
*TableauDeStringTrouve  = new std::wstring[NombreDeChampsLut];
CourElement = PremElements;
for (int Compteur = 0 ; Compteur<NombreDeChampsLut ; Compteur++)
{
(*TableauDeStringTrouve)[Compteur] = CourElement->Item;
CourElement =  CourElement->Suivant;

}
[...]
}


Donc pour le moment code fonctionnel donc pouf sauvegarde. Mais je suis un peut têtu et si tu a un peut de temps a m’accorder je voudrais comprendre pourquoi je ne peut pas utiliser les "forward_list" (et "list") ni même les "vector".

Merci pour l'info (indispensable) pour comprendre pourquoi "new" et pas "malloc" (le pire c'est que j'étais en train de pointer sur quel variable l’allocation étais faite par "new" pour faire des "delete" et idem avec "malloc"/"free"). Pourquoi ne pas avoir banni "malloc"/"free" tout de suite ??? Même moi je me comprend pas toujours

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 13 août 2012 à 11:43
0
Merci
je suis de formation C, et je doit reconnaitre que je ne connais pas encore les outils disponible en C++


Ne t'inquiète pas, ça va venir vite. Avoir une formation initiale en C est un avantage que l'on met vite à profit en C++ (la compréhension de ce qui se passe "en dessous" est toujours un plus).

Tout me semble claire mis a part les "iterators" ?


Les iterators sont une manière propre et unifiée de parcourir une collection quelque soit sa nature. Pour parcourir un arbre (std::map), une liste chaînée (std::list) ou un tableau (std::vector) on utilisera le même code. Ex:

std::vector tab;
std::list list;
std::map tree;

for (std::vector::iterator it = tab.begin(); it != tab.end(); ++it)
{
 //
}

for (std::list::iterator it = list.begin(); it != list.end(); ++it)
{
 //
}

for (std::map::iterator it = tree.begin(); it != tree.end(); ++it)
{
 //
}


Si tu remplaces "iterator", "begin" et "end", respectivement par "reverse_iterator", "rbegin", "rend", tu parcouras la collection en partant de la fin, au lieu du début, sans changer quoi que ce soit à ton code ! (Et quelque soit ta structure de donnée).

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 13 août 2012 à 11:48
0
Merci
J'ai une erreur sur l'utilisation des listes :
Error 1 error C2039: 'forward_list' : is not a member of 'std' xxxxxx.cpp 75 1 yyyyyyyy

La std::forward_list n'est disponible qu'en C++0x. La nouvelle version du C++ qui est sortit récemment. Si tu peux activer l'option -std=c++0x, tu pourras l'utiliser. En revanche, si tu n'as pas le droit à cette mouture, utilise une std::list.

Idem sur le vector :
Error 1 error C2039: 'vector' : is not a member of 'std' xxxxxx.cpp 62 1 yyyyyyyy

Je pense que tu as oublié un #include <vector>, tout simplement :p.

Pourquoi ne pas avoir banni "malloc"/"free" tout de suite ??? Même moi je me comprend pas toujours

Pour des raisons de compabilité, tout ce qui est C, est compatible en C++. malloc/free sont donc considérés comme valides en C++.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 11:51
0
Merci
Heeeeeeeeee non code fonctionnel (heeee là je comprend pas trop pourquoi par contre :



A l’exécution de cette ligne :

DecoupeLigne(LigneFichier,L"\t",&NombreItem,&ListeDonnees);
[...]
delete ListeDonnees; // <- Ici ^^


Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 13 août 2012 à 11:57
0
Merci
char DecoupeLigne(const std::wstring Ligne,const std::wstring Separateur,int* NombreDeChampsTrouve,std::wstring** TableauDeStringTrouve)
{
*TableauDeStringTrouve = new std::wstring[NombreDeChampsLut];
CourElement = PremElements;
for (int Compteur = 0 ; Compteur<NombreDeChampsLut ; Compteur++)
{
(*TableauDeStringTrouve)[Compteur] = CourElement->Item;
CourElement = CourElement->Suivant;
}
}


En C++, ça aurait plutôt cette tête là (tu noteras l'utilisation de & pour éviter les copies inutiles de ligne et separateur):
char decoupeLigne(const std::wstring& ligne, const std::wstring& separateur, std::vector<std::wstring>& tableauDeStringTrouve)
{
  //
  CourElement = PremElements;
  for (int Compteur = 0 ; Compteur < NombreDeChampsLut; ++Compteur)
  {
    tableauDeStringTrouve.push_back(CourElement->Item);
    CourElement = CourElement->Suivant;
  }
  //
}

std::vector<std::wstring> tab;
decoupeLigne(L"line", L"sep", tab);
tab.size(); // NombreDeChampsTrouve


DecoupeLigne(LigneFichier,L"\t",&NombreItem,&ListeDonnees);
[...]
delete ListeDonnees; // <- Ici ^^


J'ai besoin de voir plus de code. Notamment ce qu'est "ListeDonnees".

PS: En C++, seul les noms de classe portent une majuscule. Les attributs de classe sont suffixés par '_'.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 12:04
0
Merci
Heee oui les majuscules un peut partout sont une mauvaise habitude.

Un peut plus de code :
if (!FileSrc.bad())
{
std::wstring LigneFichier;
std::wstring* ListeDonnees;
ListeDonnees=0;
while(std::getline(FileSrc, LigneFichier))
{
int NombreItem;

NombreItem=0;
DecoupeLigne(LigneFichier,L"\t",&NombreItem,&ListeDonnees);
[...]
delete ListeDonnees;
ListeDonnees=0;
}

}


PS :
Le problème avec les vector étais bien le "#define", je regarde ça
Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 12:11
0
Merci
En faite il doit y avoir un outil qui est capable de faire ce que je veux (mm si j'aimerais bien comprendre où je merdouille quand même)
Je veux crée un tableau de chaine a partir d'une chaine et d'un séparateur (l'équivalent du "split" en VB, tout bêtement)

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 13 août 2012 à 12:24
0
Merci
Vu que ListeDonnées est un tableau intialisé par un new[], il faut faire un delete[] ListeDonnes.
Néanmoins, je récrirais le code autrement. J'écrirais carrément:

(Attention, non testé, écris de tête)
if (fileSrc)
{
  std::wstring line;
  std::vector<std::wstring> datas;
  while (std::getline(fileSrc, line)) // sous entendu std::getline(fileSrc, line, '\n')
  {
    std::wstring word;
    std::ostringstream buff;
    buff << line;
    while (std::getline(buff, word, '\t'))
      datas.push_back(word);
  }
}


On pourrait même ne faire qu'un "while (std::getline(buff, word, '\t'))" sur tout le fichier, si vraiment il n'y a que des données identiques.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 14:00
0
Merci
Hmmmmm du coup je comprend un peut mieux le "getline" (enfin je pense)

Oui je pense que je vais faire comme ça.

En effet mon dernier problème était être causé par "delete" au lieu de "delete[]".

Ta façon de faire me plais bien (imbriquer les std::getline)
Je voulais m'en sortir tout seul je n'arrive pas à bien utiliser le "wostringstream" je pense :

Ce code me donne une erreur a la compilation (enfin déjà IntelliSense) :
		if (fileSrc)
{
std::wstring line;
std::vector<std::wstring> datas;
while (std::getline(fileSrc, line)) // sous entendu std::getline(fileSrc, line, '\n')
{
std::wstring word;
std::wostringstream buff;
buff << line;
while (std::getline(buff, word, '\t')) //<- ICI
datas.push_back(word);
}
}


Erreur :
Error	1	error C2780: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : expects 2 arguments - 3 provided	xxxxxx.cpp	172	1	yyyyyyyy


Je pense que je doit convertir mon "wostringstream" en "basic_istream". Et je trouve pas . Mais en prime, ça ne risque pas de poser problème avec l’Unicode (et autre UTF8) de faire ce genre de conversion ?

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 15:06
0
Merci
OK, merci encore pour toutes ces info (je me coucherais en ayant appris quelque-chose aujourd'hui, et ça c'est bien )

J'ai plus grand chose à ajouter de mon coter tout fonctionne bien


Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
Polack77 1100 Messages postés mercredi 22 mars 2006Date d'inscription 15 avril 2018 Dernière intervention - 13 août 2012 à 15:08
0
Merci
"std:wostringstream" est en réalité alias pour le type "std::basic_istream<wchar_t>".


Je pense que tu voulais dire un "std::basic_ostream<wchar_t>"

Enfin si j'ai bien compris ^^

Amicalement
1000 recherches sur Google = 1Km de voiture en CO² (réfuté par Google )
1000 recherches sur Forestle = 100 m² de forêt tropicale sauvé .
Surfez écolo
Commenter la réponse de Polack77
cptpingu 3808 Messages postés dimanche 12 décembre 2004Date d'inscription 24 septembre 2018 Dernière intervention - 13 août 2012 à 15:22
0
Merci
Je pense que tu voulais dire un "std::basic_ostream<wchar_t>"
Enfin si j'ai bien compris ^^

Oui, c'est exactement ça. Ce n'est pas du tout une erreur d'inatttention :p, c'est pour voir si tu suivais ^^.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
Commenter la réponse de cptpingu

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.