CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

C++ fstream -> En train de virer fou

techslash
techslash
Niveau 8
04 juillet 2003 à 02:23:06

Quelqu´un peut m´expliquer pourquoi j´ai tjrs du garbage en fin de ligne lorsque je lis un fichier texte ?

J´ai essayé la méthode fopen, j´ai essayé _open et j´ai essayé de créer un stream ( ce qui me semble être la méthode la plus intéressante jusqu´à maintenant) et dans tous les cas c´est pareil, je récupère le contenu du fichier et j´ai une tale de lettres débiles et étranges en fin de ligne.

Le plus confusionnant dans tout ça c´est que le problème ne semble se produire que si le fichier lu contient des caractères avec des accents :ouch: .

Voici mon code ( tronqué pour ne montrer que l´essentiel :) ) :
---------------
// Les libs nécessaires pour que ça marche :ok:

  1. include < stdio.h>
  2. include < sys/stat.h>
  3. include < fstream>

int readTheFile()
{
struct stat fileInfo;
if(stat("fichier.txt", &) ! = 0)
{
// Le fichier n´a pas été trouvé
return 0;
}
char fileContent[fileInfo.st_size];
ifstream fileStream("palmtree.ini", ios::in);
fileStream.read(fileContent,fileInfo.st_size);
printf(fileContent);

return 1;
}
---------------
fichier.txt:
Maudit que ça marche jamais

stdout.txt:
Maudit que ça marche jamaisw…@
---------------

Merci de votre aide... ça me fait virer fou ce truc :snif2: .

techslash
techslash
Niveau 8
04 juillet 2003 à 02:26:53

:honte: Et merde, excusez moi, remplacez la ligne
ifstream fileStream("palmtree.ini", ios::in);
par
ifstream fileStream("fichier.txt", ios::in);

Dans le but de vous montrer mon code ( de façon + claire), j´ai voulu écrire fichier.txt plutôt que palmtree.ini partout et j´ai malheureusement oublié de faire le changement à cette ligne... :honte:

Donc si jamais vous trouvez une réponse à mon problème, merci bien d´men faire part :)

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 02:38:29

bah je sais pas si tu te souviens comment fonctionne les chaines de caractères ?

-> faut les terminer par le caractère nul(0) . ..

techslash
techslash
Niveau 8
04 juillet 2003 à 02:40:59

Herm... nah c´est les premières nouvelles que j´ai de ça...

La solution serait donc... ?

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 02:43:24

bin de rajouter le caractère 0 à la fin de tes données ! sinon le printf affichera le contenu de ton buffer jusqu´à rencontrer le premier 0 qu´il trouve en mémoire :

( ...)
char fileContent[fileInfo.st_size + 1];
ifstream fileStream("palmtree.ini", ios::in);
fileStream.read(fileContent,fileInfo.st_size);
fileContent[fileInfo.st_size] = 0;
printf(fileContent);
( ...)

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 02:45:19

euh j´ai pas fait gaffe sur le moment mais c´est pas très " clean" de déclarer la taille de ton buffer à partir d´une variable . .. enfin si ca marche tant mieux :)

techslash
techslash
Niveau 8
04 juillet 2003 à 02:46:44

Eh beh ça fonctionne... et dire que ça fait des semaines que je fais des recherches pour ça...

Mais dis-moi, pourquoi est-ce que c´est pas

fileContent[fileInfo.st_size + 1] = 0;

? ??

C´est ce que j´ai tenté de faire après avoir lu ta première réponse et, évidemment, ça ne fonctionne pas.

J´ai d´la théorie à revoir moi :(.

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 02:48:31

bin parceque les indices de tableaux commencent à partir de 0 . .. donc quand tu déclares :

char fileContent[N]
les indices vont de 0 à N-1 ( ce qui correspond bien à N valeurs)

ton fichier fait apparemment fileInfo.st_size donc il te faut allouer 1 caractère de plus pour le 0 de terminaison

techslash
techslash
Niveau 8
04 juillet 2003 à 02:53:18

Hmmm j´ai beaucoup de théorie à revoir là

Je déclare fileContent[fileInfo.st_size], j´obtiens une tableau de 0 jusqu´à la grosseur de mon fichier ( donc de 0 à 27 dans le cas de ´Maudit que ça marche jamais´)

Ce qui me donne déjà un caractère de plus où mettre le zéro soit fileContent[fileInfo.st_size] = 0; ou, dans ce cas-ci, fileContent[27] = 0;.

À quoi servirait le + 1 dans
char fileContent[fileInfo.st_size + 1];

?

Merci de ton aide soit dit en passant, même si je pige ± la logique, ça fonctionne :-))) .

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 02:56:51

hmm t´y es presque mais c´est pas encore tout à fait ca . ..

le fait de rajouter +1 indique qu´il faut réserver un caractère de plus pour ta chaine sinon lorsque tu écriras le 0 ca va écraser des données en mémoire ( à priori l´octer juste après ton tableau . ..)

Donc il faut obligatoirement déclarer avec le +1

char fileContent[fileInfo.st_size + 1];

si tu fais ca :
fileContent[fileInfo.st_size] = 0;

sans le +1, tu vas écraser l´octet suivant le tableau, car je te le rappelle les données s´arrêtent à fileInfo.st_size-1 ! ( d´où le +1 dans la déclaration)

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 02:58:40

si ca peut t´aider essaie de te faire le dessin du tableau avec N valeurs et regarde ce qu´il se passe pour les indices, le dernier caractère et le fait de rajouter le 0 à la fin.

A méditer . ..

Sur ce, je vais faire dodo :sleep:

techslash
techslash
Niveau 8
04 juillet 2003 à 03:01:21

Je vois donc en gros il faut toujours laissé les deux dernières " cases" d´une chaîne de caractère " libre", une pour contenir un 0 et une pour contenir l´octet qui termine la chaîne.

Eh bien parfait, merci beaucoup, ça vient de me sortir d´la p´tite flaque merdique dans laquelle je trempais depuis un bout :) .

Il faut admettre que les p´tits gars qui ont inventé le C++ ce sont donnés beaucoup de mal pour que tout soit compliqué :rire2: .

Merci encore !

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 03:02:54

" une pour contenir un 0 et une pour contenir l´octet qui termine la chaîne"

non 1 seule ! le 0 et l´octet qui termine la chaine sont les mêmes . ...

lorsque tu veux un chaine de taille N il te faut déclarer N+1 caractères ( N caractères + le caractère de fin qui est le carctère 0, ou NULL ou ´\0´ enfin ce sont toutes les mêmes valeurs)

techslash
techslash
Niveau 8
04 juillet 2003 à 03:20:21

00 | M
01 | A
02 | U
03 | D
04 | I
05 | T
06 |
07 | Q
08 | U
09 | E
10 |
11 | Ç
12 | A
13 |
14 | M
15 | A
16 | R
17 | C
18 | H
19 | E
20 |
21 | J
22 | A
23 | M
24 | A
25 | I
26 | S
------------
27 | NULL

techslash
techslash
Niveau 8
04 juillet 2003 à 03:22:44

fileInfo.st_size == 27

hmmm il me semble qu´il soit inutile de déclarer avec + 1

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 08:51:43

je répète une dernière fois... après je m´énerve ! hein!!

quand tu écris dans fileContent[27], il s´agit du 28e caractère ! ! la place en mémoire pour ce caractère n´est pas allouée si tu déclares :

char fileContent[fileInfo.st_size];

puisqu´en faisant ca tu réservres 27 caractères pas un de plus pas un de moins !

donc le dernier caractère accessible sera :

fileContent[26] ! !

Chris_le_ouf
Chris_le_ouf
Niveau 5
04 juillet 2003 à 09:19:22

L´exemple parfait du gars qui aurait dû commencer par le C ; )

regarde Tech

szString[0]
szString[1]
szString[2]

0,1,2... ça fait 3 éléments ! !! alors que le dernier élément accessible est szString[2] ! !! comme dirait Jean-Claude Vandamme : " it´s magic"

techslash
techslash
Niveau 8
04 juillet 2003 à 17:08:21

Moi je veux bien vous croire mais vous allez devoir m´expliquer pourquoi mon prog marche quand je compte à " ma façon" :( .

techslash
techslash
Niveau 8
04 juillet 2003 à 17:27:14

Hmmm j´en viens à la conclusion que j´écrivais mon 0 au-delà de mon tableau... Je vois rien d´autre. Mais si c´est bien l´cas, est-ce que ça veut dire que j´ai courru le risque d´aller écraser de l´information en mémoire appartenant à un autre prog :o)) ?

Altonfrere
Altonfrere
Niveau 10
04 juillet 2003 à 20:53:33

" Mais si c´est bien l´cas, est-ce que ça veut dire que j´ai courru le risque d´aller écraser de l´information en mémoire appartenant à un autre prog "

D´un autre prog non mais du tien oui!

Alors il se trouve que ton compilateur est gentil car tu as certainement compilé ton programme en version Debug, et le bug a pu ne pas apparaître et il faut dire qu´un dépassement de buffer d´un seul octet ca se voit pas ou ca peut ne rien faire du tout au niveau du programme ( mais c´est TRES TRES risqué et pas du tout propre).

Par contre en Release, ou si tu avais écris plusieurs octets hors des limites bin là tu aurais eu droit à un beau plantage de ton application.

Donc que tu n´arrives toujours pas à comprendre pourquoi tu as depassé je trouve qu´un dessin s´impose ! !

Relis bien les derniers posts.

Il y a d´autres raisons possibles pour que ton programme ai fonctionné sans problème mais ca devient un peu plus compliqué ( ca peut être une histoire d´alignement des données).

Pour vérifier le problème tente de compiler ca :

void main()
{
char Buffer[7] = " bonjour";
}

on est bien d´accord que la chaine " bonjour" est de longueur 7 ? ok ? Tu verras ce que te dis le compilateur . .. ( il lui manque 1 octet pour qu´il puisse y mettre le caractère NULL.

Maintenant testes ca :

  1. include < stdio.h>
  2. include < string.h>

void main()
{
char EcraseMoi = ´A´;
char Buffer[8] = " bonjour";

printf("caractere = %c / ASCII = %d\n",EcraseMoi,EcraseMoi);
printf("%s\n",Buffer);
strcpy(Buffer,"bonjours");
printf("caractere = %c / ASCII = %d\n",EcraseMoi,EcraseMoi);
}

et tires en les conclusions que tu veux . ...

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Internet
  • Macintosh
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment