OVH Cloud OVH Cloud

le pbm de l'ANTISLASH

20 réponses
Avatar
david
salut

voila mon probleme :

je suis en train de développer un ptit programme (rudimentaire) en C++
de compression de données. Je l'ai d'abord ecrit sous ouindoz et
aujourd'hui, je l'ai porté sous ... LINUX (ouais, yeepeee !!)

...MAIS... BIG problem...

TOUT marche sauf un truc : à moment donné, j'ai besoin de remplacer tous
les caractères \ avec la chaine \\.

sous ouinedo, evidement ça marche...

pas sous linux. Or la compilation se passe bien... tout se passe tres
bien... sauf evidement que la recherche du caractere \ ne donne
strictement rien.

dans le détail, voila GROSSO MODO comment je procede:
(je ne remplace pas ici un cara par une chaine, mais le pbm est
EXACTEMENT le meme)

// ------------------------------------------------
char *buffer=new[_buffer_len_];

int fp=open("mon_fichier",O_RDWR,S_IREAD|S_IWRITE);
read(fp,buffer,_buffer_len_);

for (int i=0; i<_buffer_len_; i++)
{
if (buffer[i]=='\\') buffer[i]='$';
}

write(fp,buffer,_buffer_len_);
close(fp);
delete[] buffer;
// ------------------------------------------------

voila, je n'ai pas remplacé les \ par des \\, les \ par des $.
et ça ne marche pas... aucune occurence de \ n'est trouvée

ALORS ? QUELQU'UN PEUT-IL M'AIDER ??

PLEASE ?

10 réponses

1 2
Avatar
Fabien LE LEZ
On Sat, 01 Nov 2003 23:33:50 +0100, david wrote:

char *buffer=new[_buffer_len_];


Uh ?

int fp=open("mon_fichier",O_RDWR,S_IREAD|S_IWRITE);
read(fp,buffer,_buffer_len_);


Les fonctions open et read ne font (il me semble) pas partie du
langage C++. En d'autres termes, il n'est pas choquant qu'elles
donnent des résultats différents suivant le système.

D'autre part, ce genre de techniques (tableau d'octets alloué à la
main) est plus du ressort de fr.comp.lang.c. En C++, une chaîne de
caractères s'écrit std::string. Cf n'importe quel bon bouquin de C++.

En prime, évite les identifiants commençant par "_" : une bonne partie
de ces indentifiants est réservée à l'implémenteur de la bibliothèque
standard (mais j'ai malheureusement oublié lesquels exactement :-/ ).

ALORS ? QUELQU'UN PEUT-IL M'AIDER ??


Ne crie pas ! :-<<<

--
;-)

Avatar
david
Fabien LE LEZ wrote:
On Sat, 01 Nov 2003 23:33:50 +0100, david wrote:


char *buffer=new[_buffer_len_];



Uh ?



char *buffer = new char[_buffer_len_];





int fp=open("mon_fichier",O_RDWR,S_IREAD|S_IWRITE);
read(fp,buffer,_buffer_len_);



Les fonctions open et read ne font (il me semble) pas partie du
langage C++. En d'autres termes, il n'est pas choquant qu'elles
donnent des résultats différents suivant le système.

D'autre part, ce genre de techniques (tableau d'octets alloué à la
main) est plus du ressort de fr.comp.lang.c. En C++, une chaîne de
caractères s'écrit std::string. Cf n'importe quel bon bouquin de C++.


si je ne fais pas avec, c'est que j'ai mes raisons et elles sont
suffisement bonnes, merci.


En prime, évite les identifiants commençant par "_" : une bonne partie
de ces indentifiants est réservée à l'implémenteur de la bibliothèque
standard (mais j'ai malheureusement oublié lesquels exactement :-/ ).



mais ça n'a rien à voir avec mon pbm !!
(...et la culture c'est comme la confiture, moins on en a et plus on
l'etale)




ALORS ? QUELQU'UN PEUT-IL M'AIDER ??



Ne crie pas ! :-<<<




Avatar
Vincent Richard

Fabien LE LEZ wrote:
On Sat, 01 Nov 2003 23:33:50 +0100, david wrote:
D'autre part, ce genre de techniques (tableau d'octets alloué à la
main) est plus du ressort de fr.comp.lang.c. En C++, une chaîne de
caractères s'écrit std::string. Cf n'importe quel bon bouquin de C++.


si je ne fais pas avec, c'est que j'ai mes raisons et elles sont
suffisement bonnes, merci.


Alors dans ce cas : news:fr.comp.lang.c
Si tu veux qu'on puisse t'aider, ici il faut "parler C++"...

En prime, évite les identifiants commençant par "_" : une bonne partie
de ces indentifiants est réservée à l'implémenteur de la bibliothèque
standard (mais j'ai malheureusement oublié lesquels exactement :-/ ).


mais ça n'a rien à voir avec mon pbm !!
(...et la culture c'est comme la confiture, moins on en a et plus on
l'etale)


Non, c'est à peu près le seul rapport avec C++ que Fabien a trouvé dans
ton message. Et encore, il faut bien chercher !

Vincent

--
vmime, une bibliothèque C++ sous licence GPL pour parser et générer
des messages au format MIME : http://www.sourceforge.net/projects/vmime/


Avatar
david
Vincent Richard wrote:


Fabien LE LEZ wrote:

On Sat, 01 Nov 2003 23:33:50 +0100, david wrote:
D'autre part, ce genre de techniques (tableau d'octets alloué à la
main) est plus du ressort de fr.comp.lang.c. En C++, une chaîne de
caractères s'écrit std::string. Cf n'importe quel bon bouquin de C++.


si je ne fais pas avec, c'est que j'ai mes raisons et elles sont
suffisement bonnes, merci.



Alors dans ce cas : news:fr.comp.lang.c
Si tu veux qu'on puisse t'aider, ici il faut "parler C++"...


En prime, évite les identifiants commençant par "_" : une bonne partie
de ces indentifiants est réservée à l'implémenteur de la bibliothèque
standard (mais j'ai malheureusement oublié lesquels exactement :-/ ).


mais ça n'a rien à voir avec mon pbm !!
(...et la culture c'est comme la confiture, moins on en a et plus on
l'etale)



Non, c'est à peu près le seul rapport avec C++ que Fabien a trouvé dans
ton message. Et encore, il faut bien chercher !

Vincent



sorry, mais le code que j'ai fourni est du C++, ça n'est certes pas du
C++ typique (tableau de char, open() & compagnie)

mais si les tableau de char existent encore sous C++, c'est pas pour
faire joli. Et ne t'en déplaise, si tout cela est encore là, c'est juste
parce que cela sert.



Avatar
Vincent Richard

sorry, mais le code que j'ai fourni est du C++, ça n'est certes pas du
C++ typique (tableau de char, open() & compagnie)

mais si les tableau de char existent encore sous C++, c'est pas pour
faire joli. Et ne t'en déplaise, si tout cela est encore là, c'est juste
parce que cela sert.


Si tu utilisais vraiment toutes les possibilités de C++, tu n'aurais pas
à t'embêter avec ces tableaux de 'char'.

Les tableaux de 'char' (et d'autres types) sont des fonctionnalités de bas
niveau que tu ne devrais pas utiliser (elles sont utilisées, entre autres,
par la bibliothèque standard (STL) pour proposer des objets de plus haut
niveau comme std::string, std::vector, etc...).

Maintenant, si tu tiens absolument à programmer comme on le ferait en
C, je te suggère le groupe news:fr.comp.lang.c ...

Tu peux t'inspirer de ce code pour une solution à ton problème (copie
d'un précédent message que j'avais écrit (avec une petite adaptation) :

[ référence : <3ecaae63$0$4628$ ]


#include <string>
#include <fstream>
#include <iostream>
#include <string>

int main()
{
const std::string filename = "/chemin/fichier";

// Ouverture du fichier
std::ifstream inFile(filename.c_str());

if (!inFile)
{
// Traitement de l'erreur d'ouverture...
}
else
{
// Lecture du contenu
std::string data;

std::copy(std::istreambuf_iterator<std::string::value_type>(inFile),
std::istreambuf_iterator<std::string::value_type>(),
std::back_inserter(data));

// Fermeture du fichier
inFile.close();

// Remplacement
const std::string find = ""; // on cherche ''
const std::string replace = "\"; // on remplace par ''

std::string::size_type i = 0;

for ( ; (i = data.find(find, i)) != std::string::npos ; )
{
data.replace(i, find.length(), replace);
i += replace.length();
}

// Ouverture du fichier en écriture
std::ofstream outFile(filename.c_str());

if (!outFile)
{
// Traitement de l'erreur d'ouverture...
}
else
{
// Ecriture des nouvelles données
std::copy(data.begin(), data.end(),
std::ostreambuf_iterator<std::string::value_type>(outFile));

// Fermeture du fichier
outFile.close();
}
}
}


Vincent

--
vmime, une bibliothèque C++ sous licence GPL pour parser et générer
des messages au format MIME : http://www.sourceforge.net/projects/vmime/

Avatar
Laurent DELEPINE
david wrote:

char *buffer=new[_buffer_len_];

int fp=open("mon_fichier",O_RDWR,S_IREAD|S_IWRITE);
read(fp,buffer,_buffer_len_);

for (int i=0; i<_buffer_len_; i++)
{
if (buffer[i]=='') buffer[i]='$';
}

write(fp,buffer,_buffer_len_);
close(fp);
delete[] buffer;

voila, je n'ai pas remplacé les par des , les par des $.
et ça ne marche pas... aucune occurence de n'est trouvée


As tu regardé ce qui se passait a partir du rang _buffer_len_ de ton
fichier ? Parce que comme ca a vu de nez, comme tu ne reviens pas au
debut du fichier avant d'ecrire, il n'y a aucune raison que ce debut de
fichier soit modifié.


A+

LD

Avatar
Jean-Marc Bourguet
david writes:

je suis en train de développer un ptit programme (rudimentaire) en
C++ de compression de données. Je l'ai d'abord ecrit sous ouindoz et
aujourd'hui, je l'ai porté sous ... LINUX (ouais, yeepeee !!)


Donc, copie et suivi sur fr.comp.os.unix, groupe le plus adapte.

read(fp,buffer,_buffer_len_);

for (int i=0; i<_buffer_len_; i++)
{
if (buffer[i]=='') buffer[i]='$';
}

write(fp,buffer,_buffer_len_);


Faudrait penser a faire un lseek entre les read et write.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Jean-Marc Bourguet
Jean-Marc Bourguet writes:

david writes:

je suis en train de développer un ptit programme (rudimentaire) en
C++ de compression de données. Je l'ai d'abord ecrit sous ouindoz et
aujourd'hui, je l'ai porté sous ... LINUX (ouais, yeepeee !!)


Donc, copie et suivi sur fr.comp.os.unix, groupe le plus adapte.

read(fp,buffer,_buffer_len_);

for (int i=0; i<_buffer_len_; i++)
{
if (buffer[i]=='') buffer[i]='$';
}

write(fp,buffer,_buffer_len_);


Faudrait penser a faire un lseek entre les read et write.


Et aussi a cross-poster plutot que multiposter (ou mieux encore pour
cet exemple, te contenter de fr.comp.os.unix).

A+

--
Jean-Marc
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
kanze
Vincent Richard wrote
in message news:<3fa43fa5$0$2787$...

Fabien LE LEZ wrote:
On Sat, 01 Nov 2003 23:33:50 +0100, david wrote:
D'autre part, ce genre de techniques (tableau d'octets alloué à la
main) est plus du ressort de fr.comp.lang.c. En C++, une chaîne de
caractères s'écrit std::string. Cf n'importe quel bon bouquin de
C++.


si je ne fais pas avec, c'est que j'ai mes raisons et elles sont
suffisement bonnes, merci.


Alors dans ce cas : news:fr.comp.lang.c
Si tu veux qu'on puisse t'aider, ici il faut "parler C++"...


Pardon, mais ce qu'il fait, c'est bien du C++. C'est du C++ du bas
niveau, mais parfois, on est obligé à y passer ; un des arguments pour
le C++ (par rapport à d'autres langages OO), c'est qu'il est capable à
gérer des choses à ce niveau aussi.

En prime, évite les identifiants commençant par "_" : une bonne
partie de ces indentifiants est réservée à l'implémenteur de la
bibliothèque standard (mais j'ai malheureusement oublié lesquels
exactement :-/ ).


mais ça n'a rien à voir avec mon pbm !!
(...et la culture c'est comme la confiture, moins on en a et plus on
l'etale)


Non, c'est à peu près le seul rapport avec C++ que Fabien a trouvé
dans ton message. Et encore, il faut bien chercher !


Si j'ai bien compris, il a apparamment un problème C++. Il ne l'a pas
bien expliqué -- dire qu'une chose ne marche pas ne nous renseigne assez
peu. Est-ce un problème de compilation ? Ou à l'execution ? Et si à
l'execution, quel est le contenu du fichier en entrée et après
execution.

À premier égard, je trouve au moins deux choses douteuses. Tous les deux
liées effectivement aux fonctions Posix, et non C++, mais qui serait
pareil s'il s'était servi de ostream::write et de istream::read :

- c'est assez curieux d'écrire dans le même flux où on a lu sans un
seek quelque part entre les deux, et

- il vaut mieux vérifier le résultat de read -- comme la fonction
istream::read, il renvoie le nombre de caractères réelement lus.

Au delà de ça, il me faudrait davantage d'informations pour dire. A
priori, il n'a rien dans les tests qu'il fait qui doit poser un
problème.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
kanze
Vincent Richard wrote
in message news:<3fa4daa9$0$223$...

sorry, mais le code que j'ai fourni est du C++, ça n'est certes pas
du C++ typique (tableau de char, open() & compagnie)



C'est même du C++ typique. Parfois, évidemment, c'est typique parce
qu'on ne sait pas autrement. Mais d'autres fois, parce qu'il y a des
contraints externes qui l'imposent. Ne t'en fais pas ; il m'arrive
d'écrire des choses pareilles aussi.

mais si les tableau de char existent encore sous C++, c'est pas pour
faire joli. Et ne t'en déplaise, si tout cela est encore là, c'est
juste parce que cela sert.


Si tu utilisais vraiment toutes les possibilités de C++, tu n'aurais
pas à t'embêter avec ces tableaux de 'char'.


D'abord, autant que je sache, il n'a pas de problème avec des tableaux
de char. C'est possible (voire probable) qu'il pourrait faire ce qu'il
veut avec vector. En revanche, je suppose que ce qu'il a posté n'est pas
son application complète, et c'est tout à fait possible qu'il y a des
choses ailleurs qui fait que std::vector ne convient pas.

Les tableaux de 'char' (et d'autres types) sont des fonctionnalités de
bas niveau que tu ne devrais pas utiliser (elles sont utilisées, entre
autres, par la bibliothèque standard (STL) pour proposer des objets de
plus haut niveau comme std::string, std::vector, etc...).


Sauf que le code qu'il a posté *est* manifestement de ce bas niveau.

Un des grands avantages de C++, c'est qu'il permet l'accès à ce niveau
quand on en a besoin.

Maintenant, si tu tiens absolument à programmer comme on le ferait en
C, je te suggère le groupe news:fr.comp.lang.c ...


Parce que son code ne te plaît pas, il doit aller ailleurs. Depuis quand
c'est toi qui définis les règles du groupe ?

Moi, j'avoue que je commence à avoir un peu marre des gens qui envoie
les autres ailleurs dès que le code ne ressemble pas à ce qu'eux ils
font en C++. Il y a des cas évident où la question est hors sujet
(comment afficher un bouton avec Windows), mais il y en a de plus en
plus où le poster est envoyé ailleurs alors que son problème est du C++,
ou est peut-être du C++.

Tu peux t'inspirer de ce code pour une solution à ton problème (copie
d'un précédent message que j'avais écrit (avec une petite adaptation) :


Sauf que ton programme a tout une autre sémantique que le sien.

[ référence : <3ecaae63$0$4628$ ]

#include <string>
#include <fstream>
#include <iostream>
#include <string>


Deux fois <string>, mais ni <istream> ni <ostream>. Sans <istream> ni
<ostream>, ce n'est pas du C++ standard.

Et évidemment, selon le compilateur dont on est obligé à se servir,
c'est peut-être <iostream.h> et <fstream.h>. (Mais puisqu'il a parlé de
Linux, on supposera g++ post-3.0.)

int main()
{
const std::string filename = "/chemin/fichier";

// Ouverture du fichier
std::ifstream inFile(filename.c_str());


Tu pourrais expliqué pourquoi le passage par std::string ?

Et évidemment, la sémantique de ifstream::open n'est pas celui du open
de Posix. Je suppose que s'il passe par l'open de bas niveau (plutôt que
d'utiliser des fstream ou des FILE*), c'est qu'il a besoin des
fonctionnalités qui s'y trouvent, mais qui ne se trouvent pas dans les
flux classiques. (Dans mes applications, je suis obligé à travailler à
ce niveau pour prèsque tout sauf les fichiers de log.)

if (!inFile)
{
// Traitement de l'erreur d'ouverture...
}
else
{
// Lecture du contenu
std::string data;

std::copy(std::istreambuf_iterator<std::string::value_type>(inFile),
std::istreambuf_iterator<std::string::value_type>(),
std::back_inserter(data));


Ce qui ne fait pas du tout ce qu'il a fait. Il n'a lu qu'un nombre
défini des caractères au début du fichier, non tout le fichier.

Et franchement, écrire std::string::value_type à la place de char, c'est
de la masturbation mentale, ou de la complexité pour obfusquée.

// Fermeture du fichier
inFile.close();

// Remplacement
const std::string find = ""; // on cherche ''
const std::string replace = "\"; // on remplace par ''

std::string::size_type i = 0;

for ( ; (i = data.find(find, i)) != std::string::npos ; )


Juste curieux, mais pourquoi « for » et non « while » ici ?

{
data.replace(i, find.length(), replace);
i += replace.length();
}


Son problème se situait à un niveau beaucoup plus bas. Et j'aimerais
bien voir la performance de ta solution avec un fichier qui consiste en
une million de ''.

En général, sa solution est préférable à la tienne. Mais dans
l'ensemble, je n'essaierais pas une transformation en place.

// Ouverture du fichier en écriture
std::ofstream outFile(filename.c_str());

if (!outFile)
{
// Traitement de l'erreur d'ouverture...


Tu ésquisses le seul aspect intéressant. Qu'est-ce que tu fais si
l'ouverture échoue ici ?

En fait, mon commentaire sur les transformations « en place » vaut
double ici ; j'écrirais les données en sortie dans un fichier
temporaire, et seulement lors que tout c'est bien passé, je supprimerais
le fichier initial, et je rénommerais le fichier temporaire.

Avec éventuellement des précautions en ce qui concerne des hard links
possibles sous Unix.

}
else
{
// Ecriture des nouvelles données
std::copy(data.begin(), data.end(),
std::ostreambuf_iterator<std::string::value_type>(outFile));

// Fermeture du fichier
outFile.close();


Et la gestion des erreurs ?

}
}


Et le return ? Tu ne veux sûrement pas renvoyer 0 s'il y a eu une
erreur.

}


Dans l'ensemble, son essai me semblait aussi bon, sinon mieux que le
tien.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


1 2