Se connecter avec
S'enregistrer | Connectez-vous

Problème de lecture de fichier

Dernière réponse : dans Programmation

Bonjour
Voilà je veux programmer un petit programme qui "cache" un fichier text dans une image genre .bmp . En fait je veux justement vérifier si ca marche ! C'est à dire si on peut le faire sans modifier l'image de façon visible à l'oeil nu. C'est bien sur inversible pour récuperer... C'est très con et très nul informatiquement mais bon cela peur servir à passer des email sans se faire choper par les RG (encore qu'ils ne faut pas les prendre pour des cons) en passant des secrets caché dans des images anodines... ;) 

voici le programme (c'est ultra basique)

  1. #include <iostream>
  2. #include <string>
  3. #include <fstream>
  4. using namespace std;
  5.  
  6. const
  7. rapport=20;//on veut par exemple remplacer, discretos un pixel sur 20 par un élément du texte
  8. const
  9. debut=1000;//estimation rapide de l'entête d'un fichier au format bmp
  10. char nomtexte[14]="texte.txt";
  11. char nomimage[14]="image.bmp";
  12. char nomsortie[14]="sortie.bmp";
  13.  
  14. int main(void)
  15. {
  16. ifstream image;
  17. ifstream texte;
  18. ofstream sortie;
  19. char pixel,lettre;
  20. int i=0;
  21. image.open(nomimage);
  22. texte.open(nomtexte);
  23. sortie.open(nomsortie);
  24.  
  25. for(int j=0;j<debut;j++) //C'est pour ne pas affecter les param du bmp
  26. {
  27. image.get(pixel);
  28. sortie.put(pixel);
  29.  
  30. };
  31.  
  32. while(!(image.eof()))
  33. {
  34. i=i++;
  35. if (i==rapport) //la hop on insère le caractère du fichier texte (une fois que i a atteind la valeur "rapport")
  36. {
  37. i=0;
  38. if (!texte.eof())
  39. {
  40. image.get(pixel); //il faut remplacer donc on continu de lire l'image
  41. texte.get(lettre);
  42. sortie.put(lettre);
  43. }
  44.  
  45. }
  46. else
  47. {
  48. image.get(pixel);//là on fait que copier pixel à pixel image.bmp dans sortie.bmp
  49. sortie.put(pixel);
  50. }
  51.  
  52. };
  53.  
  54. image.close();
  55. texte.close();
  56. sortie.close();
  57.  
  58. return 0;
  59. }


C'est très simple et pourtant il y un problème :
le booléen image.eof() se vérifie bien avant la fin du fichier image.bmp. j'ai testé et le programme copie bien les 1000 premier caractères du fichier image.bmp sur sortie.bmp sans problème puis ensuite image.eof() est toujours vrai (donc le fichier est considérer comme fini).
Pouvez vous m'aider ? Sur le net je n'ai que des infos sur les anciennes version de eof sur C (EOF) qui posait poblème.
Est un problème de caractère ascii ? ou ai-je fait une grossière erreur ?
Si oui comment lire un fichier octet par octet autrement ?

Autres pages sur : probleme lecture fichier

Lassé par la pub ? Créez un compte
Expert Programmation

d'ici je vois que t'est sous windows

windows est l'un des derniers OS a ouvrir ses fichiers en mode ''texte'', c'est a dire que des caracteres comme EOF peuvent purement et simplement empecher la lecture des octets suivant ...

faut ouvrir ton fichier en mode binaire, il faut passer un deuxieme argument au constructeur, je crois que c'est ios::binary ou un truc dans ce goût la ...

Mais non Windows c'est ce qui a de mieux !
Moi je connais pas du tout ta méthode pour lire les fichiers, pour lire par octets je fais comme ca :

char a;

FILE *file;
file=fopen("./nom.txt","r");

a=fgetc(file);
while (a!=EOF)
{
a=fgetc(file);
}
fclose(file);

J'ai jamais eut de problème avec ça pour les fichiers textes, mais pour les images c'est vrai que ca peut bugger, faut alors utiliser les fonctions binaire (read() et write() ), tu pouras trouver beaucoup beacoup d'info la dessu sur le net.
Expert Programmation

lord_sector a dit :
Mais non Windows c'est ce qui a de mieux ![...]
file=fopen("./nom.txt","r");
(oh une notation unix)
lord_sector a dit :

a=fgetc(file);
while (a!=EOF)
{
a=fgetc(file);
}

mince alors, a quoi ça servais déjà dowhile() ?
  1. do {
  2. a=fgetc(file);
  3. while (a!=EOF);


on peut très bien utiliser des fichiers binaires avec fopen et fgets, par exemple :
  1. char a,s[2];
  2. FILE* file;
  3. if (!(file=fopen("./nom.txt,"rb"))
  4. Y_A_UNE_ERREUR(errno);
  5. while(1) {
  6. if (!fgets(&s[0],2,file)) {
  7. if (errno) {
  8. Y_A_UNE_ERREUR(errno);
  9. } else {
  10. break;
  11. }
  12. }
  13. a=s[0];
  14. }
  15. if (!fclose(file))
  16. Y_A_UNE_ERREUR(errno);

elch a dit :

mince alors, a quoi ça servais déjà dowhile() ?
  1. do {
  2. a=fgetc(file);
  3. while (a!=EOF);



La seule différence que je connaisse entre un
  1. while(condition) { instructions; }
et un
  1. do { instructions; } while(condition);
c'est :
  • dans le 1er cas la condition est testée avant de rentrer dans le while
  • dans le 2ème tu exécutes au moins une fois les instructions de la boucle while avant de tester la condition.
    Donc dans le 1er cas, tu peux très bien ne jamais rentrer dans ta boucle.

    EDIT :
    ... zut j'avais pas vu l'instruction
    1. a=fgetc(file);
    avant sa boucle while ...
    Donc ton do{}while() est effectivement utile ici :D 

    lord_sector a dit :
    Mais non Windows c'est ce qui a de mieux !
    Moi je connais pas du tout ta méthode pour lire les fichiers, pour lire par octets je fais comme ca :

    char a;

    FILE *file;
    file=fopen("./nom.txt","r");

    a=fgetc(file);
    while (a!=EOF)
    {
    a=fgetc(file);
    }
    fclose(file);

    J'ai jamais eut de problème avec ça pour les fichiers textes, mais pour les images c'est vrai que ca peut bugger, faut alors utiliser les fonctions binaire (read() et write() ), tu pouras trouver beaucoup beacoup d'info la dessu sur le net.

    on a dit en cpp !
    les FILE* c'est en C, et encore...

    lord_sector a dit :

    Moi je connais pas du tout ta méthode pour lire les fichiers, pour lire par octets je fais comme ca :

    char a;

    FILE *file;
    file=fopen("./nom.txt","r");

    a=fgetc(file);
    while (a!=EOF)
    {
    a=fgetc(file);
    }
    fclose(file);

    Non. fgetc() retoure un int. a doit donc être obligatoirement de type int et non char, sinon, EOF (int < 0) risque d'être détecté de façon erronée.
    Citation :

    J'ai jamais eut de problème avec ça pour les fichiers textes, mais pour les images c'est vrai que ca peut bugger, faut alors utiliser les fonctions binaire (read() et write() ), tu pouras trouver beaucoup beacoup d'info la dessu sur le net.

    Tu peux parfaitement lire du binaire avec ce code (corrigé) à condition d'ouvrir le fichier en mode binaire ("rb").

    elch a dit :
    (oh une notation unix)

    Fonctionne aussi sous Windows.
    Citation :

    mince alors, a quoi ça servais déjà dowhile() ?
    1. do {
    2. a=fgetc(file);
    3. while (a!=EOF);


    L'expression idiomatique est plutôt
    1. int c;
    2. while ((c=fgetc(file)) != EOF)
    3. {
    4. /* processing c ... */
    5. }

    Citation :
    on peut très bien utiliser des fichiers binaires avec fopen et fgets, par exemple :

    Déconseillé. fgets() est orienté ligne de texte. On a pas d'info de longueur lue. Il peut y avoir des 0 au milieu de la ligne. D'autre part, fgets() ajoute un 0 final... Bref, on va rien retrouver du tout. Quel est le problème avec fread() qui est fait pour ça ?

    http://mapage.noos.fr/emdel/notes.htm#fichiers

    En tout cas ce qui suit, comme cela m'avait été conseiller au début marche très bien avec N'IMPORTE QUEL FICHIER:

    1. #include <fstream>
    2. using namespace std;
    3. int main(void)
    4. {
    5. char c;
    6. char nomimage[14]="image.bmp";
    7. ifstream image(nomimage,ios::in | ios::binary);
    8. while(!(image.eof()))
    9. {
    10. c=image.get(pixel);
    11. //blablabla "j'utilise c"
    12. };
    13.  
    14. return 0;
    15. }
    Lassé par la pub ? Créez un compte