Pointer en écriture dans un txt

Maz -  
 Maz -
Bonjour,

Je travail sous Dev-c++ et j'essaye de faire pointer, en écriture, dans un endroit voulu de mon fichier txt.
L'inscription en début et fin de fichier ne pose aucun probleme, mais je n'arrive pas a pointer au milieu du fichier ou à la 3eme ligne par exemple.

Fonction :

bool enregistrerCompteur(string& pieceChoisie, string &user)
{
time_t secondes; //initialise le nombre de second (récupere le temps depuis le 1er janvier 1970
struct tm instant; //Initialisation de la structure
time(&secondes); //récupere le temps actuelle (secondes)
instant=*localtime(&secondes); //remplie la structure - local grâce au localtime()
int i =0;
string ligne;
string chaine1, chaine2;

fstream fichier("commande.txt", ios::in | ios::out /*| ios::ate*/);
if(fichier)
{
while(!fichier.eof())
{
fichier >> chaine1 >> chaine2;
if(chaine1 == user && chaine2 == "finCmd")
{

fichier.seekp(0, ios::cur);

fichier<<"\n =================="<< user <<"CMD" << i << "=========================== \n" << "Date_de_commande : " << instant.tm_mday << "/" << instant.tm_mon << endl << "Compteur " << pieceChoisie << endl << "Accessoire(s) : " << endl;
fichier.close();
return true;

}

i++;
}

fichier << user << " " << instant.tm_mday << "/" << instant.tm_mon << endl << "Compteur " << pieceChoisie << endl << "Accessoire(s) : " << endl;
return true;

}
}

La partie qui m'interesse est celle-ci :

if(chaine1 == user && chaine2 == "finCmd")
{

fichier.seekp(0, ios::cur);

fichier<<"\n =================="<< user <<"CMD" << i << "=========================== \n" << "Date_de_commande : " << instant.tm_mday << "/" << instant.tm_mon << endl << "Compteur " << pieceChoisie << endl << "Accessoire(s) : " << endl;
fichier.close();
return true;

}
Mais le pointeur ne pointe pas a l'endroit où ma chaine1 = user et ma chaine2 = finCmd.

bref, quelqu'un peut m'aider?
A voir également:

4 réponses

Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
https://en.cppreference.com/w/cpp/io/basic_ostream/seekp
déjà, tu lui dit de ne pas bouger à ton code, c'est logique qu'il ne pointe pas là où il faut :
fichier.seekp(0, ios::cur);
tu te déplaces de 0 octet depuis ta position actuelle, or, tu es à la fin de ta ligne puisque tu l'as lu.
Je me pose une question sur les flux bidirectionnel in/out, car il y a seekg et seekp, y a t il 2 pointeurs 1 pour la lecture et un pour l'écriture ou est-ce le même ? Selon le cas, il faut faire ton opération différemment.
0
Maz
 
Il y a effectivement 1 pointeur en écriture et 1 pointeur en lecture. Seekp() est un pointeur en lecteur et le seekg() en écriture.
J'ai testé en modifiant le 0 de ma commande fichier.seekp(0, ios::cur)

Si je met 150, par exemple, il se déplace sur la meme ligne mais a la 150eme position. Mais ce n'est pas un probleme pour le moment vu qu'il n'arrive pas a écrire à l'endroit voulu... Je 'marrangerais plus tard avec la position sur la ligne.

fichier.seekp(0,ios::cur) : J'interprete cette commande de la facon suivante : je place mon pointure d'écriture sur l'octet 0 de ma ligne courante. Or il n'arrive pas a définir ma ligne courante...
0
Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
J'interprete cette commande de la facon suivante : je place mon pointure d'écriture sur l'octet 0 de ma ligne courante.
Où as tu vu ça ? Il n'y a pas de notion de ligne, c'est la position para rapport au début du fichier. Un fichier n'a qu'une dimension, les lignes ne sont que des caractères indicateurs de mise en forme.
Je pense que tu n'as pas bien compris comment fonctionne un fichier, et je pense que tu va avoir des surprises par la suite si tu modifie ta ligne par une ligne de taille différente.
0
Maz
 
Remplace ligne courante par position courante. Je n'ai pas utilisé le bon terme.

Et oui ma ligne change de taille selon le nom de l'utilisateur... Dans ce cas il faut que je me place a la fin de ma variable chaine2. Le problème est que je n'arrive deja pas a pointer sur cette ligne pour écrire à la suite.

Je n'ai peut etre pas compris oui, mais si on se place en début et fin de fichier, à quoi sert la ios::cur ? Elle n'est pas sensé récupérer la position actuelle ?
0
Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
si, mais de quel pointeur ?
Ce que je ferais et qui devrait fonctionné :
int pos=0;
while(!fichier.eof())
{
  pos=fichier.tellg();// on prend la position du pointeur de lecture
  fichier >> chaine1 >> chaine2;
  if(chaine1 == user && chaine2 == "finCmd")
  {

    fichier.seekp(pos);//on place le pointeur d'écriture au début de la ligne

    fichier<<"\n =================="<< user <<"CMD" << i << "=========================== \n" << "Date_de_commande : " << instant.tm_mday << "/" << instant.tm_mon << endl << "Compteur " << pieceChoisie << endl << "Accessoire(s) : " << endl;
    fichier.close();
    return true;

  } 

Je comprends mal où tu veux mettre ton pointeur. As tu bien compris que ce que tu écris supprimera ce qui suis ?
0
Maz
 
Et non... Effectivement j'ai été stupide d'oublier ce détail... Est-il possible d'écrire à un moment donné dans le fichier txt sans pour autant effacer la suite?
0
Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Est-il possible d'écrire à un moment donné dans le fichier txt sans pour autant effacer la suite?
Non.

Solutions :
- charger le fichier en mémoire, insérer le texte que tu veux dedans, écraser le fichier d'origine avec ce qu'il y a en mémoire ;
- faire un fichier texte pour chaque "user", ce qui permet de facilement ajouter du texte.
0
Maz
 
Erf... C'est pas tres propre et en cas de fichier tres gros ca sera dur... Et aucune bibliothèque ne peut arranger ça?

Sinon tant pis, je prendrais la 2eme solution.

Quoiqu'il en soit, merci pour ton aide, cela m'a permis d'y voir plus claire.
0
Char Snipeur Messages postés 10112 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Tu peux éventuellement retrouver une bibliothèque qui fasse une insertion en fichier texte, mais de manière interne elle fera ce que je t'ai dit. Il faut bien voir que dans un fichier les bit sont cote à cote. Pour insérer du texte il faut obligatoirement déplacer ce qu'il y a après. Une solution est de prévoir de la place de libre, mais dans ton cas c'est hors de question.
Cette méthode est très propre, elle est juste pas très élégante du point de vue conceptuel.
une troisième solution est d'empiler les résultats et de temps à autre de reformater le fichier final. Un ordinateur fonctionne de manière séquentiel.
Tu peu compléter la deuxième solution en faisant un troisième fichier INDEX qui répertorie les autres fichier en les incluant en lien, type un fichier XML.
0
Maz
 
Ca marche, merci pour tes aides précieuses, détaillées et surtout rapides :)

Juste en passant, je travail avec Dev-c++ sous windows xp sp3. J'utilise le compilateur d'origine de Dev-c++.
Je souhaiterais empecher l'utilisateur de saisir des lettres et des caractères spéciaux. Il ne doit saisir que des numériques.
Eventuellement, pour corcé un peu, les activés et désactivés à ma guise dans certaines parties du soft
0