Lecture ligne par ligne de fichier txt en C++pour re-jeu de données Temps Reel

DamienR83 Messages postés 6 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 2 juin 2010 - 29 avril 2010 à 12:04
DamienR83 Messages postés 6 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 2 juin 2010 - 30 avril 2010 à 10:32
Bonjour,

Je souhaite faire une API en C++ avec un affichage de données en "pseudo temps-réel". L'ensemble des mes données sont déjà enregistrées par colonnes (séparées par des tabulations) avant que je lance mon programme. Je veux donc rejouer les données en simulation.

Mes données sont rangées par colonne, chaque ligne représentant des états de capteurs à un instant précis. Ma fonction actuelle (download_datas()) me permet de lire 1 ligne du fichier txt et de récupérer les données sous forme de double dans un tableau (qui est utilisé derrière par d'autres fonctions).

Je voudrais faire en sorte de pouvoir basculer d'une ligne à une autre pour lire les données à un instant, puis au suivant... mais sans avoir à relire toutes les données à chaque appel de ma fonction.
En effet, avec des centaines de paramètres et des dizaines de milliers de lignes je ne peux pas lire et mémoriser tout d'un coup au lancement de mon API (Stack overflow...).
Il me faut donc pourvoir choisir de lire à tout instant de telle à telle ligne du fichier text, sans devoir scanner tout le fichier text à chaque appel de ma fonction (toutes les 20ms, si possible) car si je fais quelque chose du genre:
"charger puis scaner tous les strings en partant du début jusqu'à tomber à tel string qui correspond au premier élement de la ligne 78956ième ligne)" ça va pas aller du tout au niveau temsp réel...

Voici ma fonction actuelle de récupération des données:


FILE*fichier;
static int NOMBRE_DE_COLONNES=301;
static double donnees[300];

void mon_programme::download_datas(void)
{

// Stockage des données dans un tableau temporaire de strings appelé
// "ligne":

using namespace std;
string ligne[301];
char nom[256]="mon_fichier_text.txt";
ifstream fichier(nom);
for (int i=1 ; i<NOMBRE_DE_COLONNES ; i++)
{
fichier>>ligne[i];
}
fichier.close();

// Convertion des strings en double et insertion dans le tableau appelé
// "donnees":

vector<string>parametre(ligne,ligne+NOMBRE_DE_COLONNES);
vector<string>::iterator iter;
iter=parametre.begin();
iter++;
for(int r=1 ; r<NOMBRE_DE_COLONNES ; r++)
{
string aaa=*iter;
std::string c(aaa);
std::istringstream i(c);
double nombre;
i >> nombre;
donnees[r]=nombre;
iter++;
}
}

Si j'ai été assez clair et précis, quelqu'un aurait-il une idée de ce que je pourrais faire? J'ai pensé aussi à utiliser les listes (#include <list>) que je trouve assez pratiques pour se déplacer avec des itérateurs, mais cette fois aussi ça implique que j'ai enregistré avec "fichier>>ligne[i];" toutes les lignes de mon fichier txt pour ensuite me déplacer dans ligne[]...
Y aurait-il un moyen par exemple de se déplacer dans le fichier txt avec par exemple des pointeurs sans devoir le charger au préalable? J'ai cherché dans les forums mais je n'ai trouvé rien qui correspondait à mon besoin...

Merci d'avance, ne serait-ce pour avoir lu jusqu'au bout :)

7 réponses

DamienR83 Messages postés 6 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 2 juin 2010
29 avril 2010 à 12:07
ah oui j'oubliais, je travail sur Microsoft Visual C++ 2008 Express Edition.
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
29 avril 2010 à 13:06
Quand on doit manipuler d'énormes masses de données et pouvoir pointer direct où on veut, faut oublier la notion de "lignz" et tout ce qui est fichier texte.
Enregistre tes données direct en binaire en STRUCT par enreg, ce qui te permettra d'aller direct prendre celle que tu voudras.

ciao...
BruNews, MVP VC++
0
TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
29 avril 2010 à 13:10
Salut,

En effet, avec des centaines de paramètres et des dizaines de milliers de lignes je ne peux pas lire et mémoriser tout d'un coup au lancement de mon API (Stack overflow...).

Et microsoft inventa MapViewOfFile() pour compenser l'inexistance de mmap() sur windows. Normalement le système gérera (presque) toujours mieux la mémoire lui même que tout ce que tu peux faire avec ta lecture ligne par ligne ou autre système fait maison.
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
29 avril 2010 à 13:19
Très bien le FileMapping mais tant qu'il gardera la notion de ligne, il n'y aura pas moyen de pointer sirect sur l'enreg voulu.

ciao...
BruNews, MVP VC++
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
TychoBrahe Messages postés 1309 Date d'inscription samedi 31 janvier 2009 Statut Membre Dernière intervention 5 juin 2013 12
29 avril 2010 à 18:45
Très bien le FileMapping mais tant qu'il gardera la notion de ligne, il n'y aura pas moyen de pointer sirect sur l'enreg voulu.

Avec des lignes ayant toutes le même nombre de colonnes (ce que j'avai cru comprendre à cause de l'utilisation de NOMBRE_DE_COLONNES), une simple opération sur un pointeur donne la ligne souhaitée. Après je connais mal le C++ et le code m'est un peu étranger, désolé si j'ai mal compris ce point là.
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
29 avril 2010 à 21:36
Pas du tout, NOMBRE_DE_COLONNE n'indique rien sur la longueur d'une ligne, seulement combien de séparateurs dans la ligne.

ciao...
BruNews, MVP VC++
0
DamienR83 Messages postés 6 Date d'inscription jeudi 29 avril 2010 Statut Membre Dernière intervention 2 juin 2010
30 avril 2010 à 10:32
Bonjour,

Tout d'abord merci pour vos réponses...

Je connais le nombre de colonnes (chaque colonne correspondant à l'un des paramètres que je dois récupérer), il y en a NOMBRE_DE_COLONNES. NOMBRE_DE_COLONNE représente donc aussi (à +- 1 prés) le nombre de séparateurs dans la ligne.


J'ai essayé MapViewofFile() comme suit (majoritairement copié honteusement sur des posts de forums):

void mon_filemapping(void)
{
char *file_map;
HANDLE fd = NULL;
HANDLE fm = NULL;
DWORD size=8;

file_map = "mon_texte.txt";
fd = CreateFile (file_map, FILE_READ_DATA, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
fm = CreateFileMapping(fd,NULL,PAGE_READONLY,0,size,NULL);

if (!fm)
{
printf ("error when creating\n");
}

LPVOID data;
data = MapViewOfFile(fm, FILE_MAP_READ, 0, 0, size);

char *data_c;
data_c= static_cast<char *>(VirtualAlloc(0, size+1, 0, PAGE_READWRITE));

if (!data)
{
printf ("error when viewing\n");
}

printf ("data : %c \n", data_c);

UnmapViewOfFile(data);
CloseHandle(fm);
}


Mais ça ne marche pas... sachant que pour faire des essais et simplifier la chose j'ai mis dans mon_texte.txt seulement 2 nombres écrits comme ceci: "12" ou comme ceci: "1 tabulation 2". J'ai essayé avec plusieurs combinaisons mais avec cette version là mon programme m'affiche "data: " => sans afficher de char... en essayant avec des doubles je n'y arrive pas non plus.
1 char 1 octet 8 bits
avec 2 charactères, size = 16 bits devrait être bon?



Sinon, est ce qu'une "list" ou un "vector" sont limités en taille?
Car je pourrait créer une classe contenants autant d'attributs (des list ou des vector) que de paramètres (c'est à dire qu'il y en aurait NOMBRE_DE_COLONNES), et enregistrer toutes les valeurs de mon fichier texte dedans.
Ainsi je lirait la première ligne de mon fichier texte, je rangerait dans la première case de chaque attribut la valeur dans la colonne correspondant, ensuite je supprime cette ligne dans le fichier texte et je recommence en copiant les données dans les case suivante etc...

Ceci me prendrait un court instant ou peut être quelques secondes mais seulement lors de l'initialisation de mon programme, et ensuite pour mon Re-Jeu je n'aurai qu'à aller chercher les valeurs de chaque paramètre à la position voulue dans les list ou vector de ma classe (ce qui devrait, je l'espère, être assez peu gourmand en ressources).

Qu'en dites vous?

Merci
0
Rejoignez-nous