IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

lecture fichier ligne a ligne


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2007
    Messages : 245
    Points : 110
    Points
    110
    Par défaut lecture fichier ligne a ligne
    Bonjour,

    Je me remet au C/C++ après de longue années où je ne l'utilisais pas et évidemment je galère...

    j'essaye d'ouvrir des fichiers contenant un header puis une image codée en 16 bit.
    (ça ressemble au dicom mais c'est un peu différent c'est des fichiers .vff de chez ge).

    là j'en suis à essayer de lire ligne à ligne le header pour récuperer les informations.

    j'ai fait ça pour le moment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <sys/types.h>
    #include <dirent.h>
    #include <errno.h>
    #include <vector>
    #include <conio.h>
    #include <algorithm>
    #include <functional>
    #include <iterator>
     
    using namespace std;
     
    /*function getdir*/
    int getdir (string dir, vector<string> &files)
    {
    DIR *dp;
    struct dirent *dirp;
    if((dp = opendir(dir.c_str())) == NULL) {
    cout << "Error(" << errno << ") opening " << dir << endl;
    return errno;
    }
     
    while ((dirp = readdir(dp)) != NULL) {
    files.push_back(string(dirp->d_name));
    }
    closedir(dp);
    return 0;
    }
    // end function getdir
     
    //function main
    int main()
    {
     
    vector<string> files = vector<string>();
    string input = "";
    FILE *input_file; 
     
    // How to get a string/sentence with spaces
    cout << "Enter the path of the folder where there is only the projections :\n>";
    getline(cin, input);
     
    getdir(input,files);
     
    for (unsigned int i = 0;i < files.size();i++) {
    cout << files[i] << endl;
    }
     
    getch();
     
    vector<const char*> starts;
     
    transform( files.begin(), files.end(), back_inserter( starts ), mem_fun( &string::c_str ) );
     
    const char** arr = &starts.front();
     
    for (unsigned int i = 0;i < starts.size();i++) 
    {
    /* Read projection file*/
    if ((input_file = fopen(starts[i], "r")) == NULL)
    {
    fprintf(stderr,  "Cannot open input file \n" );
    }
     
    input_file = fopen(starts[i], "r");
     
    /* Read the header */
     
    std::string line;
    getline(input_file,line);
    cout << line << endl;
     
    }
     
    }
    et je n'arrive pas à compiler à cause de l'avant dernière ligne avec getline.
    je sais que files est bien rempli comme il faut.
    il a l'air d'ouvrir input_file correctement aussi.

    quand je compile il me fait l'erreur :
    "no matching function for call to getline(FILE*&,std::string&)"

    j'ai essayé de changer la nature de line mais ça n'a rien changé.

    je comprend pas trop parce que sur internet je vois des forums où il est dit que getline s'utilise comme ça.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Citation Envoyé par svagrim Voir le message
    j'ai essayé de changer la nature de line mais ça n'a rien changé.
    Et pour cause, c'est input_file le problème.
    FILE* c'est du vieux C, pourquoi ne pas utiliser un ifstream ? Qui serait lui utilisable avec getline

    http://www.cplusplus.com/reference/string/getline/
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Ce n'est jamais une bonne idée de mélanger des types C et C++.
    N'utilise pas de FILE*, mais plutôt des std::ifstream. Du coup le dernier getline fonctionnera, puisque qu'il attend un type C++ istream (dont ifstream hérite) et non pas un FILE*.

    Utilise std::cin.get() au lieu de getch(), std::cerr<<"erreur" au lieu de fprintf(stderr, "erreur"), etc.

    Aussi, peux-tu me dire à quoi sert starts puisque starts[i] est strictement équivalent à files[i].c_str() ?

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2007
    Messages : 245
    Points : 110
    Points
    110
    Par défaut
    merci pour vos réponses.

    je reprend effectivement des bouts de vieux codes que j'avais fait il y a bien longtemps du coup c'est vrai que j'ai un peu du mal à les mettre ensemble.

    pour le starts et le files, je sais plus...
    il y a une fonction qui ne passait pas avec files du coup j'avais généré starts pour que le format concorde à ce que la fonction voulait.

    mais après j'ai modifié files.
    du coup c'est sans doute redondant maintenant oui.

    merci pour les infos en tout cas ! j'essaye tout ça.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2007
    Messages : 245
    Points : 110
    Points
    110
    Par défaut
    j'ai un probleme avec ifstream maintenant

    j'ai changé le code en ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <sys/types.h>
    #include <dirent.h>
    #include <errno.h>
    #include <vector>
    #include <conio.h>
    #include <algorithm>
    #include <functional>
    #include <iterator>
     
    using namespace std;
     
    /*function getdir*/
    int getdir (string dir, vector<string> &files)
    {
    DIR *dp;
    struct dirent *dirp;
    if((dp = opendir(dir.c_str())) == NULL) {
    cout << "Error(" << errno << ") opening " << dir << endl;
    return errno;
    }
     
    while ((dirp = readdir(dp)) != NULL) {
    files.push_back(string(dirp->d_name));
    }
    closedir(dp);
    return 0;
    }
    // end function getdir
     
    //function main
    int main()
    {
     
    vector<string> files = vector<string>();
    string input = "";
     
     
    // How to get a string/sentence with spaces
    cout << "Enter the path of the folder where there is only the projections :\n>";
    getline(cin, input);
     
    getdir(input,files);
     
    for (unsigned int i = 0;i < files.size();i++) {
    cout << files[i] << endl;
    }
     
    std::cin.get();
     
    for (unsigned int i = 0;i < files.size();i++) 
    {
    /* Read projection file*/
     
      ifstream input_file;
     
      input_file.open (files[i], ifstream::in);
     
    //ifstream input_file(files[i], ios::in);
     
    if(input_file)
    {
    std::cerr<<"Cannot open input file \n";
    }
    /* Read the header */
     
    std::string line;
    getline(input_file,line);
    cout << line << endl;
     
    }
    et quand je veux compiler j'ai cette erreur :
    no matching function for call to `std::basic_ifstream<char, std::char_traits<char> >::open(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const std::_Ios_Openmode&)'

    vous avez une idée ?
    c'est files[i] le problème maintenant ?

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    http://www.cplusplus.com/reference/f...ifstream/open/

    Comme précisé dans la doc, il faut obligatoirement un const char* en argument ; donc appeler std::string::c_str() (j'imagine que les concepteurs de la STL voulaient limiter l'interdépendance des classes).

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2007
    Messages : 245
    Points : 110
    Points
    110
    Par défaut
    oki
    du coup maintenant ça compile, ça tourne

    et le problème maintenant c'est que j'ai rajouté un while pour lire toutes les lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            while ( std::getline(input_file, line ) )
            {
                cout << "while" << endl;
                // afficher la ligne à l'écran
                std::cout << line << std::endl;   
            }
    et qu'a un moment donnée ce n'est plus du texte du header, mais c'est l'image codé en 16 bit.
    comment je peux faire pour lui faire comprendre qu'à un moment donné il ne faut plus lire la ligne, mais toute l'image ?

    merci en tout cas déjà pour la solution au début du problème !

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    118
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 118
    Points : 158
    Points
    158
    Par défaut
    Logiquement si tu lis une image, alors le fichier est formatté d'une certaine manière (en l'occurence le format est vff). Ainsi tu dois pouvoir trouver un champ dans le header à une position fixe indiquant le début des pixels de l'image.

    Une fois cette info trouvée, il est simple de récupérer les pixels :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #include <fstream>
     
    using namespace std;
     
    int main() {
    	fstream f("test.bmp", fstream::in | fstream::binary);
    	unsigned int offset_data = /* offset permettant de retrouver le début des données */
            streamsize length;
    	char* bitmap_array;
     
            /* On détermine la taille du fichier en plaçant le curseur à la fin du fichier */
    	f.seekg(0, fstream::end);
    	length = f.tellg();
     
            /* On dimensionne le tableau qui va stocker la totalité du fichier en mémoire */
    	bitmap_array = new char[length];
     
            /* On replace le curseur au début du fichier, puis on stocke tout le fichier en mémoire */
            f.seekg(0, fstream::beg);
    	f.read(bitmap_array, length);
     
            /* les données commencent à bitmap_array + offset */
     
            /* désallocation du tableau dynamique */
            delete[] bitmap_array;
     
            return 0;
    }

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juin 2007
    Messages : 245
    Points : 110
    Points
    110
    Par défaut
    hum je trouve pas de champ avec indiqué l'offset.

    par contre toutes les lignes qui font parti du header (donc avant l'image) comporte le signe égal, sauf la première.
    du coup je vais essayer de me baser là dessus.
    tester si y a un signe égale sur la ligne, et si non lire la suite en temps qu'image.

    merci en tout cas pour vos réponses !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture fichier texte : Derniere ligne en double(probleme)
    Par Ephemarius dans le forum Débuter
    Réponses: 2
    Dernier message: 05/10/2014, 00h13
  2. Réponses: 9
    Dernier message: 03/07/2014, 18h08
  3. lire fichier .txt (NOTEPAD) ligne par ligne
    Par skambram dans le forum VB.NET
    Réponses: 1
    Dernier message: 06/06/2009, 18h41
  4. lire un fichier de string ligne par ligne
    Par bilzzbenzbilz dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 11/02/2009, 10h44
  5. Réponses: 6
    Dernier message: 20/07/2007, 15h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo