OVH Cloud OVH Cloud

Chaine de caracteres..

11 réponses
Avatar
Julien
Bonjour,

Désolé, je maitrise pas specialement le C++ donc je risque de poser une
question... euh con.
J'ai un léger problème avec une chaine de caractères.. Mon code :

unsigned char tampon[16];
ifstream source;
char buf;

source.open("data.txt",ios::in|ios::binary);
for (i=0;i<16;i++)
{
source.get(buf);
tampon[i]=buf;
}

Et lorsque j'affiche le resultat, je me retrouve avec une chaine de
16octets (avec sizeof) de longueur 19 (avec strlen) et quand j'affiche,
forcement les 16 premiers caracteres sont bons, mais les 3 derniers
ressemblent a rien forcement...
Je cherche a recuperer une suite de 16 octets dans le fichier et c'est
la seule methode que j'ai trouvé...
Si quelqu'un pouvait m'aider, sur la longueur de la chaine ou sur une
autre methode pour recuperer une suite d'octets, qu'il hésite pas !!

MERCI

10 réponses

1 2
Avatar
M. B.
"Julien" a écrit dans le message de
news: bs2ide$d92$
Bonjour,

Désolé, je maitrise pas specialement le C++ donc je risque de poser une
question... euh con.
J'ai un léger problème avec une chaine de caractères.. Mon code :

unsigned char tampon[16];
ifstream source;
char buf;

source.open("data.txt",ios::in|ios::binary);
for (i=0;i<16;i++)
{
source.get(buf);
tampon[i]=buf;
}

Et lorsque j'affiche le resultat, je me retrouve avec une chaine de
16octets (avec sizeof) de longueur 19 (avec strlen) et quand j'affiche,
forcement les 16 premiers caracteres sont bons, mais les 3 derniers
ressemblent a rien forcement...
Je cherche a recuperer une suite de 16 octets dans le fichier et c'est
la seule methode que j'ai trouvé...
Si quelqu'un pouvait m'aider, sur la longueur de la chaine ou sur une
autre methode pour recuperer une suite d'octets, qu'il hésite pas !!

MERCI



Ton tampon doit faire 17 caracteres pour en stocker 16, car il faut mettre
le caractere nul de fin de chaine a la derniere position.

MB

Avatar
Alexandre
unsigned char tampon[16];
ifstream source;
char buf;

source.open("data.txt",ios::in|ios::binary);
for (i=0;i<16;i++)
{
source.get(buf);
tampon[i]=buf;
}


Problème : en C, une chaine de caractère *doit* se terminer par le caractère
0. Donc, le code correct serait :
unsigned char tampon[17];
ifstream source;
char buf;

source.open("data.txt",ios::in|ios::binary);
for (i=0;i<16;i++)
{
source.get(buf);
tampon[i]=buf;
}
tampon[16]=0;


Et lorsque j'affiche le resultat, je me retrouve avec une chaine de
16octets (avec sizeof) de longueur 19 (avec strlen) et quand j'affiche,
forcement les 16 premiers caracteres sont bons, mais les 3 derniers
ressemblent a rien forcement...


Normal , voir + haut.

Je cherche a recuperer une suite de 16 octets dans le fichier et c'est
la seule methode que j'ai trouvé...
Si quelqu'un pouvait m'aider, sur la longueur de la chaine ou sur une
autre methode pour recuperer une suite d'octets, qu'il hésite pas !!

MERCI


Un conseil : en C++, oublies les chaines type "C" avec un tableau de char.
Utilises plutôt la classe std::string qui a l'avantage de gérer elle-même la
mémoire nécessaire. Ton code deviendrait :

std::string Tampon;
ifstream source;
char buf;

source.open("data.txt",ios::in|ios::binary);
for (i=0;i<16;i++)
{
source.get(buf);
tampon += buf;
}

En passant, dans un code sérieux, évite les "nombres magiques" comme 16 :
pourquoi 16 ? Qqn qui lirait le code se poserait fatalement ce genre de
question... Emploie par exemple :
#define TAILLE 16

(...) for(i=0;i<TAILLE;i++) (...)

ou mieux,
const int TAILLE = 16;
à la place du #define

A+

Avatar
Fabien LE LEZ
On Sun, 21 Dec 2003 17:55:56 +0100, "Alexandre"
wrote:

Emploie par exemple :
#define TAILLE 16


NOOOOON !

unsigned const TAILLE_CHAINE= 16;

--
;-)

Avatar
James Kanze
"M. B." writes:

|> "Julien" a écrit dans le
|> message de news: bs2ide$d92$

|> > Désolé, je maitrise pas specialement le C++ donc je risque
|> > de poser une question... euh con.
|> > J'ai un léger problème avec une chaine de caractères.. Mon code :

|> > unsigned char tampon[16];
|> > ifstream source;
|> > char buf;

|> > source.open("data.txt",ios::in|ios::binary);
|> > for (i=0;i<16;i++)
|> > {
|> > source.get(buf);
|> > tampon[i]=buf;
|> > }

|> > Et lorsque j'affiche le resultat, je me retrouve avec une chaine
|> > de 16octets (avec sizeof) de longueur 19 (avec strlen) et quand
|> > j'affiche, forcement les 16 premiers caracteres sont bons, mais
|> > les 3 derniers ressemblent a rien forcement... Je cherche a
|> > recuperer une suite de 16 octets dans le fichier et c'est la seule
|> > methode que j'ai trouvé... Si quelqu'un pouvait m'aider, sur la
|> > longueur de la chaine ou sur une autre methode pour recuperer une
|> > suite d'octets, qu'il hésite pas !!

|> Ton tampon doit faire 17 caracteres pour en stocker 16, car il faut
|> mettre le caractere nul de fin de chaine a la derniere position.

Je crois qu'il y a un problème plus profond que ça. Je me
démande ce qu'il veut faire réelement, parce qu'il ouvre le
fichier en binaire, et le buffer c'est unsigned char, et non char. Si le
but est réelement de lire du binaire, il y a une fonction read pour
le faire. Ce qu'il a fait vaut aussi, mais en revanche, l'utilisation de
strlen n'est pas valid, parce qu'évidemment, du binaire n'est pas
forcement une chaîne de caractères.

Si son but est de lire une chaîne de caractères, évidemment, il
ne faut pas ouvrir le fichier en binaire, le type d'une chaîne de
caractères est std::string, et non unsigned char[], et évidemment,
pour en avoir la longueur, c'est la fonction membre size().

--
James Kanze mailto:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
Avatar
Julien
Fabien LE LEZ wrote:

Emploie par exemple :
#define TAILLE 16



NOOOOON !

unsigned const TAILLE_CHAINE= 16;



Euuh ah ? C'est pas bien le #define ??? :-)


Avatar
Florent C.
Julien wrote:

Fabien LE LEZ wrote:


Emploie par exemple :
#define TAILLE 16




NOOOOON !

unsigned const TAILLE_CHAINE= 16;



Euuh ah ? C'est pas bien le #define ??? :-)

On devrait réserver #define à l'écriture de macros (et encore) et à la

compilation conditionnelle, et le proscrir pour la définition des
constantes. En effet, on a un mot-clé pour ça alors pourquoi ne pas
l'utiliser ?
De plus, const permet de donner un type aux constantes, ce que ne permet
pas #define, et ça c'est mâââl ...

~flure()



Avatar
Alexandre
"Fabien LE LEZ" a écrit dans le message de
news:
On Sun, 21 Dec 2003 17:55:56 +0100, "Alexandre"
wrote:

Emploie par exemple :
#define TAILLE 16


NOOOOON !

unsigned const TAILLE_CHAINE= 16;

--
Si tu avais lu mon message jusqu'au bout, c'est exactement ce que je dis 3

lignes plus bas.
Le #define est + connu de la plupart des gens, c'est pour ça que j'en
parlais.
Sinon, tout à fait d'accord, une macro définie n'est pas typée,
contrairement à un const int.


Avatar
Gabriel Dos Reis
"Alexandre" writes:

| Le #define est + connu de la plupart des gens,

C'est le résultat d'un sondage Ifop-Sofres-Alexandre ?
Avatar
Fabien LE LEZ
On Mon, 22 Dec 2003 16:30:19 +0100, "Alexandre"
wrote:

Le #define est + connu de la plupart des gens


De la plupart des programmeurs C, tu veux dire.
Ici le #define n'est pas une solution acceptable.

--
;-)

Avatar
Fabien LE LEZ
On Mon, 22 Dec 2003 13:42:16 +0100, Julien
wrote:

Euuh ah ? C'est pas bien le #define ?


Pas dans ce cas.

Imagine le résultat :

void f()
{
#define TAILLE 15
//...
}

class C
{
public:
//...
private:
int TAILLE;
};


Autre exemple, un peu plus tordu :

class C
{
public:
void SetWindowText();
void SetWindowTextW();
};

Ce code fonctionnera parfaitement sur pas mal de systèmes... Sauf sous
Windows, si le fichier winuser.h est #inclus (il l'est pour toute
application utilisant les API Win32), et que la compilation se fait en
Unicode. Pourquoi ? Parce que le fameux fichier winuser.h contient le
code suivant :

#ifdef UNICODE
#define SetWindowText SetWindowTextW
#else
#define SetWindowText SetWindowTextA
#endif // !UNICODE

Un bel exemple des ravages de #define... Presque aussi savoureux que
que BOOL à trois états dont je parlais dans
<news: ;-)


--
;-)

1 2