il sagis de double un \ en \ évidemment c’est pas faute d’avoir essayer.
pour les quote j’y suis arriver:
/*
ce code a pour but de doubler une quote, ce code fonctionne, je voudrai faire la meme chose pour les \ mai la évidament sa marche pas
j'ai bien tenter en doublant les \\ sans succès
*/
#include <iostream>
#include <string>
int main()
{
size_t found;
string str ("/'home/'user4/'Téléchargements/'tmp/'mon fichier");
string str2 ("'");
int N = 0;
while(found!=string::npos){
if (N==0)
{
found=str.find(str2);
str.replace(found,str2.length(),"''");
found=str.find("'",found + 2,1);
N++;
}
else
{
str.replace(found,str2.length(),"''");
found=str.find("'",found + 2,1);
}
}
cout << str << endl;
}
si j’essaye avec des \ ou \\ sa par en vrille
Merci d’avance
La seule chose que je vois n’a strictement rien à voir avec les antislash : quand tu fais tourner l’algo avec n’importe quel caractère qui n’existe pas dans ta chaîne, ça plante car ton algo est buggé :
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::replace
Abandon
C’est un bête problème d’initialisation de ta boucle, que tu as essayé de contourner en doublant le corps de la boucle alors qu’il n’y en a pas besoin en réalité. Je te laisse chercher un peu, tu devrais avoir suffisamment d’indices avec ça pour refaire ton algo. Demande si tu veux la solution.
Étape suivante une fois que ça fonctionnera : la même chose, mais avec une seule allocation mémoire quel que soit le nombre d’occurrences à remplacer.
[quote=« syam »]
C’est un bête problème d’initialisation de ta boucle, que tu as essayé de contourner en doublant le corps de la boucle alors qu’il n’y en a pas besoin en réalité. Je te laisse chercher un peu, tu devrais avoir suffisamment d’indices avec ça pour refaire ton algo. Demande si tu veux la solution.
Étape suivante une fois que ça fonctionnera : la même chose, mais avec une seule allocation mémoire quel que soit le nombre d’occurrences à remplacer. [/quote]
Bon finalement j’ai trouver un moyen mai même en modifiant le teste de la boucle, pas moyen de ce passé du if ,donc je donne ma langue aux chat
Rooh je t’ai dit pourtant. C’est juste un souci d’initialisation de la boucle.
[code]#include #include
using namespace std;
int main()
{
string str = “/home/user4/Téléchargements/tmp/mon fichier”;
// chaînes de recherche / remplacement (const car ça ne changera pas)
// ça évite d’avoir à changer la valeur partout dans le code
const string search_str = “quelque chose”;
const string replace_str = “autre chose”;
// ça c’est juste pour éviter de recalculer les longueurs des chaînes à chaque itération
const size_t search_len = search_str.length();
const size_t replace_len = replace_str.length();
// on cherche la première occurrence
size_t found = str.find(search_str);
// on n’exécute le corps de la boucle que s’il y a quelque chose à remplacer
while (found != string::npos)
{
// on a trouvé une occurrence à remplacer, on effectue le remplacement
str.replace(found, search_len, replace_str);
// on cherche l’éventuelle occurrence suivante
found = str.find(search_str, found + replace_len);
}
cout << str << endl;
return 0;
}[/code]
[quote=« syam »]Rooh je t’ai dit pourtant. C’est juste un souci d’initialisation de la boucle.
[code]#include #include
using namespace std;
int main()
{
string str = « /home/user4/Téléchargements/tmp/mon fichier »;
// chaînes de recherche / remplacement (const car ça ne changera pas)
// ça évite d’avoir à changer la valeur partout dans le code
const string search_str = « quelque chose »;
const string replace_str = « autre chose »;
// ça c’est juste pour éviter de recalculer les longueurs des chaînes à chaque itération
const size_t search_len = search_str.length();
const size_t replace_len = replace_str.length();
// on cherche la première occurrence
size_t found = str.find(search_str);
// on n’exécute le corps de la boucle que s’il y a quelque chose à remplacer
while (found != string::npos)
{
// on a trouvé une occurrence à remplacer, on effectue le remplacement
str.replace(found, search_len, replace_str);
// on cherche l’éventuelle occurrence suivante
found = str.find(search_str, found + replace_len);
}
cout << str << endl;
return 0;
}[/code][/quote]
l’idée de metre la longueur de la chaine est bonne j’y avais pas penser
par contre ton code marche pour les caractère autre que celui la → \
essaye avec:
string str = "/home/user4/Télécha\\rgemen\\ts/tmp/mon fichier";
// chaînes de recherche / remplacement (const car ça ne changera pas)
// ça évite d'avoir à changer la valeur partout dans le code
const string search_str = "//";
const string replace_str = "////";
// ça c'est juste pour éviter de recalculer les longueurs des chaînes à chaque itération
const size_t search_len = search_str.length();
const size_t replace_len = replace_str.length();
// on cherche la première occurrence
size_t found = str.find(search_str);
// on n'exécute le corps de la boucle que s'il y a quelque chose à remplacer
while (found != string::npos)
{
// on a trouvé une occurrence à remplacer, on effectue le remplacement
str.replace(found, search_len, replace_str);
// on cherche l'éventuelle occurrence suivante
found = str.find(search_str, found + replace_len);
}
cout << str << endl;
Pourquoi veux-tu qu’il te remplace la séquence // dans ta chaîne alors qu’elle n’est pas présente ?
Essaye avec juste / tu verras que ça marche très bien (pas besoin de le doubler comme un antislash, y’a rien à échapper là…).
Personnellement quand j’ai initialisation - test de sortie - mise à jour de l’initialisation, j’utilise systématiquement un for.
J’ai eu un peu de temps libre cet après midi du coup je l’ai fait comme ça :
void duplique(const char car, std::string & chaine)
{
using namespace std;
for(size_t found = chaine.find(car, 0); string::npos != found; found = chaine.find(car, found + 2)){
chaine.insert(found, 1, car);
}
}
Mais mon code ne répond qu’au doublement d’un caractère.
Ensuite pour éviter d’avoir plus d’une ré-allocation :
size_t count = 0;
for(size_t found = chaine.find(car, 0); string::npos != found; found = chaine.find(car, found + 2)){
count++;
}
chaine.resize(chaine.size() + count);
for(size_t found = chaine.find(car, 0); string::npos != found; found = chaine.find(car, found + 2)){
chaine.insert(found, 1, car);
}
}[/code]
La l’évitement de la ré-allocation engendre un surcoût (on passe de O(N) à O(2N), mais ça ne change pas la complexité de l’algorithme (il reste en O(N). On pourrait faire mumuse et se contenter d’un std:string::reserve() de la 1.5 fois la taille de la chaîne ce qu’on peut penser être une bonne médiane entre éviter le déplacement de la chaîne en mémoire, mais ça n’a pas d’intérêt et la fiabilité est fortement dépendante du code.
Remarque : Stocker la taille des std::string c’est de la microoptimisation, si je me souviens bien ça permet juste d’éviter un appel de méthode car std::string stocke elle même la taille de la chaîne et la place réservée.
Il n’y a aucune garantie que la taille de la chaîne soit stockée, c’est dépendant de l’implémentation STL que tu utilises.
Héritage : string (21.2) → basic_string (21.3) → Sequence (23.1.1) → Container (23.1)
Dans tout ça, le seul endroit où il est fait référence à size() (dont length() n’est qu’un alias) c’est dans la spécification des Containers :
[quote=« C++ ISO/IEC 14882:2003 »]23.1 table 65expression return_type operational semantics complexity
...
a.size() size_type a.end()-a.begin() (Note A)
...
Those entries marked ‘‘(Note A)’’ should have constant complexity. [et non pas must][/quote]
Et en l’absence de garantie, hein…
Bon ben je vai dormir moins C..
Merci pour vos réponse
le problème de ‹ › et \ viend de postgresql qui ne supporte pas ce type de donnée.
mai sa ce complique encore parce que il va faloir que je place [quote]E’mavaleur’[/quote] avec en plus [quote]E’le c++ est d'or’[/quote]
c’est compliquer juste pour insérer des donnée pff
Mai je comprend pas pourquoi il ne ce sont pas baser sur la longueur de la string…
Si je lis correctement entre les lignes, tu fais du remplacement de chaîne dans une requête SQL, et en plus tu essayes de gérer manuellement l’encodage de la chaîne pour qu’il soit compatible avec PostgreSQL, c’est ça ?
Bon je connais pas l’API C/C++ de PostgreSQL, mais toutes les bases de données un tant soit peu fonctionnelles ont une API pour remplacer les paramètres dans la requête sans avoir à faire ça soi-même, et sans avoir à s’occuper de l’encodage / échappement. Quelque chose du genre :
requete = db.Query("SELECT * FROM table WHERE champ1=%1 AND champ2!=%2");
requete.Param(1).AsString("valeur1");
requete.Param(2).AsInt32(372);
if (requete.Execute())
...
Je ne doute pas qu’en cherchant un peu dans la doc, tu trouveras une fonctionnalité équivalente pour PostgreSQL. Même SQLite a ça !
Si seulement c’était aussi simple… Je vais pas détailler le pourquoi du comment (ça risquerait de raviver mes envies de meurtre*) mais le fait est qu’on se coltine 4 compilos / environnements différents pour un même produit, selon l’époque à laquelle a été initialement écrit tel ou tel exécutable. Dont une monstruosité 16 bits qui date des années 90, à l’époque de Windows 3.1 (et après on se demande pourquoi je hais** Windows…).
(*) Très lent, le meurtre. D’aucuns appelleraient ça de la torture sadique, si je pouvais m’y adonner (et si je retrouvais le(s) coupable(s)).
(**) Le mot est très faible.
Forcément dans ces conditions, t’imagines bien que quand j’entends « changer d’implémentation » ça a tendance à me faire bondir.
[quote=“syam”]Si je lis correctement entre les lignes, tu fais du remplacement de chaîne dans une requête SQL, et en plus tu essayes de gérer manuellement l’encodage de la chaîne pour qu’il soit compatible avec PostgreSQL, c’est ça ?
[/quote]
oui
[code]
Bon je connais pas l’API C/C++ de PostgreSQL, mais toutes les bases de données un tant soit peu fonctionnelles ont une API pour remplacer les paramètres dans la requête sans avoir à faire ça soi-même, et sans avoir à s’occuper de l’encodage / échappement. Quelque chose du genre :
requete = db.Query("SELECT * FROM table WHERE champ1=%1 AND champ2!=%2");
requete.Param(1).AsString("valeur1");
requete.Param(2).AsInt32(372);
if (requete.Execute())
...
On est deux alors, je n’ai absolument aucun courage pour quoi que ce soit aujourd’hui. [/quote]
Moi j’ai une bonne raison, je suis en bépo sur un clavier typematrix