Buffer

nidhaletec Messages postés 44 Date d'inscription jeudi 12 juin 2008 Statut Membre Dernière intervention 28 mars 2009 - 14 juin 2008 à 15:18
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 - 16 juin 2008 à 13:15
est ce que c vrai que je dois utiliser un buffer pour me placer dans un fichier à partir d un programme en C++ en prenant comme référence de placement un mot déjà  éxistant dans le fichier ?


si oui je cherche des ressources qui m éxplique .<!-- nothing comment -->

3 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
14 juin 2008 à 22:20
Salut,

Bin non, tu n'es pas obligé d'utilisé un buffer : tu peux utiliser seekg. Quoique cela peux aider côté perfs.

Vala un exemple :
<hr />// load a file into memory
#include
#include <fstream>
#include <string.h>
#include <stdlib.h>

using namespace std;

/**
 * Renvoie la taille d'un fichier.
 *
 * Le stream doit être ouvert en binary.
 *
 * @param is Stream du fichier dont on souhaite connaître la taille.
 * @return La taille du fichier.
 */
int GetFileSize(ifstream& is)
{
  int nCurrentPos;   // Position courante dans le stream
  int nLength;       // Taille du stream

  // Sauvegarde de la postion actuelle pour restitution
  nCurrentPos = is.tellg();

  // On va en fin de fichier
  is.seekg (nCurrentPos, ios::end);

  // La position courante est la taille du fichier
  nLength = is.tellg();

  // Restitution de la position originale
  is.seekg(nCurrentPos, ios::beg);

  return nLength;
}

/**
 * Recherche une chaîne dans un stream.
 *
 * La recherche commence à partir de la position courante.
 * Le flux est mis en place près à lire la chaîne trouvée.
 *
 * @param is Stream dans lequel rechercher la chaîne.
 * @param s Chaîne à rechercher dans le stream.
 * @return true si le mot à été trouvé, false sinon.
 */
bool FindInFile(ifstream &is, string s)
{
  int nLength;        // Taille du fichier
  char * lpBuffer;    // Tampon de lecture
  int nCurrentPos;    // Position courante dans le fichier

  // Si recherche d'une chaîne vide, on sort
  if (s.size() < 1) return true;

  // Sauvegarde de la postion actuelle pour restitution
  nCurrentPos = is.tellg();

  // Allocation d'un buffer de la taille du mot recherché
  lpBuffer = new char [s.size() + 1];

  // Récupération de la taille du fichier
  nLength = GetFileSize(is);

  // Tant que l'on peut lire autant de caractère qu'il y en a dans la chaîne
  while ((nLength - nCurrentPos) >= (int)s.size())
  {
    is.read(lpBuffer, s.size());

    // Mise en place d'un zéro terminal pour la comparaison
    lpBuffer[s.size()] = '\0';

    // Si les chaînes sont identiques
    if (! strcmp(lpBuffer, s.c_str()))
    {
      // On retourne au début de la chaîne
      is.seekg(nCurrentPos, ios::beg);
      delete[] lpBuffer;
      return true;
    }

    // Il faut avancer caractère par caractère
    nCurrentPos++;
    is.seekg(nCurrentPos, ios::beg);
  }

  // Restitution de la position originale
  delete[] lpBuffer;
  return false;
}

string FindWord(string fileName, string s)
{
  int nLength;
  char * lpBuffer;
  string result;

  // Allocation d'un buffer de la taille du mot recherché
  lpBuffer = new char [s.size() + 1];

  // Ouverture du fichier
  ifstream is;
  is.open(fileName.c_str(), ios::binary);
  if (! is.is_open())
  {
    delete[] lpBuffer;
    throw "Echec de l'ouverture du fichier " + fileName;
  }

  // Récupération de la taille du fichier
  nLength = GetFileSize(is);

  // Recherche du mot
  if (FindInFile(is, s))
  {
    // Récupération du mot pour affichage
    is.read(lpBuffer, nLength);
    lpBuffer[s.size()] = '\0';
    result = lpBuffer;

    delete[] lpBuffer;
    is.close();
    return result;
  }
  else
  {
    delete[] lpBuffer;
    is.close();
    throw "Chaîne introvable";
  }
}

int main ()
{
  int result;  // Code de retour du programme

  try
  {
    cout << FindWord("test.txt", "toto") << endl;
    result = 0;
  }
  catch (string s)
  {
    cout << "Problème lors de la récupération du mot situé avant toto dans le fichier test.txt : " << endl << s << endl;
    result = 1;
  }

  system("pause");
  return result;
}
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
14 juin 2008 à 23:04
Franchement, tant qu'à faire une lecture caractère par caractère, je dirais OUI il est obligatoire d'utiliser un buffer, du moins, si on tient un minimum au performance parce que là...

try/catch OUFFFFF. Jette un coup d'oeil au listing. C'est dégouttant.

Aussi, il a oublié de préciser ici qu'il souhaite écraser le mot trouvé par un autre. Pas le choix de passer par un buffer dans ce cas (surtout si le mot remplaçant est plus long que le mot à remplacer).
C++ (@++)<!--
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
16 juin 2008 à 13:15
Ah tiens il y a au moins une erreur dans ce que j'ai écrit :

Dans GetFileSize :
is.seekg (nCurrentPos, ios::end); -> is.seekg(0, ios::end);
0
Rejoignez-nous