Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Membre régulier
    Inscrit en
    juin 2007
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : juin 2007
    Messages : 236
    Points : 72
    Points
    72

    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 :
    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
    Modérateur

    Homme Profil pro Cyrille
    Network programmer
    Inscrit en
    juin 2010
    Messages
    2 178
    Détails du profil
    Informations personnelles :
    Nom : Homme Cyrille
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Network programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 2 178
    Points : 5 644
    Points
    5 644

    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/

  3. #3
    Membre émérite
    Inscrit en
    décembre 2008
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : décembre 2008
    Messages : 533
    Points : 866
    Points
    866

    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
    Inscrit en
    juin 2007
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : juin 2007
    Messages : 236
    Points : 72
    Points
    72

    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
    Inscrit en
    juin 2007
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : juin 2007
    Messages : 236
    Points : 72
    Points
    72

    Par défaut

    j'ai un probleme avec ifstream maintenant

    j'ai changé le code en ça :
    Code :
    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 émérite
    Inscrit en
    décembre 2008
    Messages
    533
    Détails du profil
    Informations forums :
    Inscription : décembre 2008
    Messages : 533
    Points : 866
    Points
    866

    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
    Inscrit en
    juin 2007
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : juin 2007
    Messages : 236
    Points : 72
    Points
    72

    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 :
    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é
    Inscrit en
    mars 2010
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : mars 2010
    Messages : 118
    Points : 134
    Points
    134

    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 :
    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
    Inscrit en
    juin 2007
    Messages
    236
    Détails du profil
    Informations forums :
    Inscription : juin 2007
    Messages : 236
    Points : 72
    Points
    72

    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.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •