Bjr,
Dans la cellule d'un TStringGrid j'ai par exemple nuage,soleil,pluton
Est ce qu'il existe un moyen de récupérer uniquement ce qu'il y a entre les virgules?
Version imprimable
Bjr,
Dans la cellule d'un TStringGrid j'ai par exemple nuage,soleil,pluton
Est ce qu'il existe un moyen de récupérer uniquement ce qu'il y a entre les virgules?
Oui, en découpant ta chaine de caractère...
Regarde du coté des fonctions Pos et SubString
Exemple:
Code:
1
2
3
4
5
6 AnsiString tmp = StringGrid1->Cells[x][y] ;//'nuage,soleil,pluton' int pos1 = tmp.Pos(",") ; //pos1=6 AnsiString end = tmp.SubString(pos1+1, tmp.Length() ); //'soleil,pluton' int pos2 = end.Pos(","); //pos2=7 AnsiString middle = end.SubString(1,pos2-1); // 'soleil' ShowMessage( middle ) ;
tu peux utiliser DelimitedText de TStringList
la Fonction ExtractsStrings
Ou coder ta propre fonction Explode comme le propose sat83
Code XE (bon ça existe au moins depuis Delphi 6)
Edit : je suis développeur Delphi, le TSysCharSet c'est un type ordinal en delphi (un simple entier utilisé en binaire de 1 à 32 octets)Code:
1
2
3
4 TStrings *Items = new TStringList(); if (ExtractStrings(TSysCharSet() << ',', TSysCharSet(), MaChaine.w_str(), Items))
C'est un Objet en C++, faut-il le libérer explicement ? pas de new donc pas delete, ou est-ce la portée de bloc suffit ?
Je ré-apprends mes bases ... je ne voudrais pas proposer à dekalima un code qui fuit :aie:
Malheureusement ces fonctions n'existe pas sous mon bon vieux BCB5! :cry:
Voici une petite fonction qui devrait fonctionner (je ne l'ai pas tester en détail!!!). Elle peut être améliorée/optimisée...
Qui s'utilise:Code:
1
2
3
4
5
6
7
8
9
10
11 AnsiString FindSubStringPos( AnsiString aStr, AnsiString aSep, int aPos ) { AnsiString tmp = aStr ; for( int i=1; i<aPos; i++ ) { int pos1 = tmp.Pos(",") ; tmp = tmp.SubString(pos1+1, tmp.Length() ); } int pos2 = tmp.Pos(","); return( tmp.SubString(1,pos2-1) ); }
Code:
1
2
3 ShowMessage( FindSubStringPos("aaa,bbb,ccc,ddd,", ",", 2) ) ; //bbb ShowMessage( FindSubStringPos("aaa,bbb,ccc,ddd,", ",", 3) ) ; //ccc ShowMessage( FindSubStringPos("aaa,bbb,ccc,ddd,", ",", 4) ) ; //ddd
TStringList.DelimitedText, QuoteChar, Delimiter existe depuis Delphi 4 (du moins, je crois), c'est dingue que BCB5 ne l'ai pas !
C'est des méthodes et propriétés de l'Objet TStringList
Merci à vous deux pour vos infos...
J'ai pas trop compris ta toute dernière fonction Sat83, faudra que je la re-regarde...
Par contre dans ton premier post, j'ai complété ce que tu as mi pour afficher le debut, milieu(que tu avais fait), et la fin )
ça marche c'est bon, mais le problème que j'ai c'est que ça marche dans ce cas précis si le tmp contient 3 mots ( on a bien un premier, un milieu et un dernier) mais dans mon cas il peut y avoir 2 ou 4 mots ou même un seul ...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 void __fastcall TForm1::Button5Click(TObject *Sender) { AnsiString tmp = AdvStringGrid1->Cells[5][1] ;//'nuage,soleil,pluton' 1 change int pos1 = tmp.Pos(",") ; //pos1=6 AnsiString end = tmp.SubString(pos1+1, tmp.Length() ); //'soleil,pluton' AnsiString debut = tmp.SubString(0,pos1-1); int pos2 = end.Pos(","); //pos2=7 AnsiString middle = end.SubString(1,pos2-1); // 'soleil' AnsiString fin = end.SubString(pos2+1,tmp.Length()); ShowMessage(debut); ShowMessage( middle ) ; ShowMessage(fin); }
et je sais pas trop comment faire tout ça par contre ....
Si tu un C++Builder récent, utilise TStringList.DelimitedText ou ExtractStrings !
Il est fort possible que la Lib TMS contienne des versions plus performantes :mouarf:
Tu as pas un petit exemple d'utilisation car il n'y a pas d'exemple d'utilisation dans l'aide BCB sur DelimitedText...:?
Tu ne cherche pas bcp !
il y a encore plus pratique ! la propriété CommaText
Code XE
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 { TStringList *ListeChaine = new TStringList(); try { ListeChaine->CommaText = "nuage,soleil,pluton"; for (int i = 0; i < ListeChaine->Count; i++) { ShowMessage(ListeChaine->Strings[i]); } } __finally { delete ListeChaine; } }
Ok ça l'air de bien marcher , simplement quand je fais ceci:
j'ai cette erreur:Code:
1
2 TStringList *li = new TStringList() ; li->CommaText=AdvStringGrid1[5][1];
Je crois me souvenir qu'il y a une conversion à faire mais je me souviens plus laquelle et comment ...Citation:
[C++ Erreur] Unit1.cpp(269): E2015 Ambiguïté entre 'TComponent::operator IInterfaceComponentReference *()' et 'TComponent::operator IInterface *()'
Désolé hein , je fais pas du builder depuis longtemps...:?
Et n'oublie pas lorsque tu instancie un objet de penser à le libérer:Code:li->CommaText=AdvStringGrid1->Cells[5][1];
un:
implique un:Code:TStringList *li= new TStringList() ;
Code:delete li;
Je reviens un bon mois après car je viens de réaliser qu'avec CommaText, tout comme DelimitedText il considère que l'espace est aussi un délimiteur...
Exemple
Si j'ai plage,mouton,lune rose
il va me sortir plage, ensuite mouton , puis lune, puis rose au lieu de lune rose pour le dernier
comment lui faire comprendre que seul le "," est le délimiteur ?
Thx8-)Code:li->DelimitedText=AdvStringGrid1->Cells[5][cptrule2ord];
Si Delphi 2007+ : Voir StrictDelimiter
Si Delphi 4 à 7 : Utiliser TStringList + ExtractsStrings
Merci, j'ai essayé entre temps une autre manière: en déclarant le delimiter:
Mais rien à faire il aime pas, l'espace est toujours considéré comme un délimiteur...Code:
1
2
3 li->Delimiter=','; li->DelimitedText=AdvStringGrid1->Cells[5][cptrule2ord];
StrictDelimiter: je crois que j'ai pas dans ma version de BCB
ExtractStrings:
J'ai trouvé ça en Delphi:
Code:i := ExtractStrings([' ',',','*','(',')','+'],[' '], pchar(stri), stringLi );
Mais je pige pas trop, même avec F1...Code:
1
2
3
4 var stringli : Tstrings; begin stringli := Tstrings.Create();
Quelle horreur ! Instanciation du classe abstraite ! en plus tu as trouvé du mauvais code ! pas de chanceCode:stringli := Tstrings.Create();
Code:stringli := TStringList.Create();
:recherch:Code:TStrings stringli = new TStringList();
Je fais du C++ depuis à peine 2 mois et j'avoue que la syntaxe de ExtractStrings est un peu pénible mais je cela se trouve en cherchant ce que tu ne semble pas faire !
Tu n'as même pas vu que j'avais déjà donné la réponse dans ce même sujet dans mon message du 02/12/2010, 11h46
C++ 2007+
BCB 6-Code:
1
2
3 li->Delimiter = ','; li->StrictDelimiter = true; li->DelimitedText = AdvStringGrid1->Cells[5][cptrule2ord];
Code:
1
2
3 stringLi->Clear(); ExtractStrings(TSysCharSet() << ',', TSysCharSet(), AdvStringGrid1->Cells[5][cptrule2ord].c_str(), stringLi);
Salut dekalima
Un bout de code qui a servi a tester le separateur de fichiers CSV, ce teste permet de recuperer les chaines encadrees par un separateur qui peut etre different suivant le fichier, le teste est prevu pour une seule colonne, mais il est tres facile de l'adapter
Sur la Forme un TButton une StringGrid un TopenDialog
Le code
Code:
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 #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { String FilePath; ////////////////////////////////// // ici on appelle la boite de dialogue ouvrir un fichier // avec les options et le filtre OpenDialog1->Options.Clear(); OpenDialog1->Options << ofAllowMultiSelect << ofFileMustExist; OpenDialog1->Filter = "Fichiers TSP (*.TSP) (*.tsp)|*.tsp|Fichiers DOC (*.DOC) (*.doc)|*.doc|Fichiers CSV (*.CSV) (*.csv)|*.csv"; OpenDialog1->FilterIndex = 1; // demarre le dialogue d'affichage des fichiers /////////////////////////////////// if(OpenDialog1->Execute()) { FilePath = OpenDialog1->FileName; } /////////////////////////////////// // ici on va charger la StringGrid avec le fichier int i; int j; char a; AnsiString convertisseur; TStringList *MyStringList = new TStringList(); MyStringList->LoadFromFile(FilePath); //Si tu as créer ton extension lors de la sauvegarde, penses à réutiliser la même ici. StringGrid1->ColCount=1;//cela met la grille à une seule colonne de base StringGrid1->RowCount=1;//cela met la grille à une seule ligne de base for(i=0;i<MyStringList->Count;i++) { convertisseur=MyStringList->Strings[i]; convertisseur = convertisseur + ";"; // teste pour trouver les separateurs en fonction on modifie // (convertisseur.Pos("\t")); if (convertisseur.Pos("\t") > 0) { a = '\t'; } else if (convertisseur.Pos("\;") > 0) { a = '\;'; } else if (convertisseur.Pos("\,") > 0) { a = '\,'; } else if (convertisseur.Pos(" ") > 0) { int ii = convertisseur.Pos(" "); a = a++; //StringGrid1->DefaultColWidth = 200; //StringGrid1->RowCount = a; //StringGrid1->Rows[i]->Text = convertisseur; } else if (convertisseur.Pos("\n") > 0) { a = a++; } else if (convertisseur.Pos("\r") > 0) { a = a++; } StringGrid1->DefaultColWidth = 300; StringGrid1->RowCount = a; StringGrid1->Rows[i]->Text = convertisseur; //} // on va chercher le separateur soit ( "\t" ) soit ( "\;" ) soit ( "\," ) //for(j=0;(convertisseur.Pos(a)>=1);j++) //{ // on va chercher le separateur soit ( "\t" ) soit ( "\;" ) soit ( "\," ) //convertisseur[convertisseur.Pos(a)]='\n'; //voir s'il faut ajouter un test sur le cas où j=0 //if(j>StringGrid1->ColCount) //{ //StringGrid1->ColCount = j; //Il est possible que cela soit un j-1 ou un j+1... //StringGrid1->ColCount = j; //Il est possible que cela soit un j-1 ou un j+1... //} //if(i>(StringGrid1->RowCount-1)) //{ //StringGrid1->RowCount = i+1; //StringGrid1->Rows[i]->Text = convertisseur; // x correspond à la ligne, 0 pour la première, souvent grisée //} //}//fin du for } delete MyStringList; //si cette ligne te poses un soucis essayes de la supprimer: en théorie elle est nécessaire. //} }
Merci à vous, je vais me débrouiller avec ça!