Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++
C++ Forum d'entraide technique sur le langage C++. Avant de poster -> F.A.Q C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 04/01/2013, 20h44   #1
svagrim
Membre du Club
 
Inscription : juin 2007
Messages : 203
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 203
Points : 62
Points : 62
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.
svagrim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 21h04   #2
Bousk
Modérateur
 
Homme Cyrille
Network programmer
Inscription : juin 2010
Messages : 1 545
Détails du profil
Informations personnelles :
Nom : Homme Cyrille
Âge : 25
Localisation : France

Informations professionnelles :
Activité : Network programmer

Informations forums :
Inscription : juin 2010
Messages : 1 545
Points : 4 086
Points : 4 086
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/
Bousk est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 21h30   #3
cob59
Membre chevronné
 
Inscription : décembre 2008
Messages : 490
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 490
Points : 751
Points : 751
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() ?
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 21h46   #4
svagrim
Membre du Club
 
Inscription : juin 2007
Messages : 203
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 203
Points : 62
Points : 62
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.
svagrim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 22h03   #5
svagrim
Membre du Club
 
Inscription : juin 2007
Messages : 203
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 203
Points : 62
Points : 62
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 ?
svagrim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2013, 22h20   #6
cob59
Membre chevronné
 
Inscription : décembre 2008
Messages : 490
Détails du profil
Informations forums :
Inscription : décembre 2008
Messages : 490
Points : 751
Points : 751
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).
cob59 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/01/2013, 00h40   #7
svagrim
Membre du Club
 
Inscription : juin 2007
Messages : 203
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 203
Points : 62
Points : 62
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 !
svagrim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/01/2013, 06h54   #8
backlash
Membre habitué
 
Inscription : mars 2010
Messages : 114
Détails du profil
Informations forums :
Inscription : mars 2010
Messages : 114
Points : 119
Points : 119
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;
}
backlash est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2013, 19h57   #9
svagrim
Membre du Club
 
Inscription : juin 2007
Messages : 203
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 203
Points : 62
Points : 62
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 !
svagrim est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 20h30.


 
 
 
 
Partenaires

Hébergement Web