éliminer les caractères de ponctuation d'un texte

Résolu
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015 - 30 juin 2010 à 11:54
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015 - 30 juin 2010 à 18:23
bonjour,
ce programme permet d'éliminer la ponctuation du texte, sauf si les caractères de ponctuation sont compris entre 2 chiffres, ils sont alors gardés;

#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <vcl.h>


int main(void)
{
  FILE *stream, *stream1;
  int actuel 0, avant 0, avant_avant = 0 ;

  stream = fopen("in.txt", "r+");
  stream1 = fopen("out.txt", "w+");

  do
  {
avant_avant = avant;
avant = actuel;
actuel = fgetc(stream);
if (actuel == EOF)
  break;

if (isdigit(actuel) && (avant =='.'||avant ==',' || avant == ':') &&
isdigit(avant_avant))
  fprintf(stream1, "%c%c", avant, actuel);
  	else if (actuel != '.' && actuel != ':' && actuel != '"' && actuel != '/' && actuel != ')' && actuel != '(' && actuel != ',' && actuel != '}' && actuel != '{' && actuel != '+')
  fprintf(stream1, "%c", actuel);
  } while (actuel != EOF);

  fclose(stream);
  fclose(stream1);

  return 0;
}

mais j'ai un petit soucis; parfois je trouve dans des textes de tels nombres : 22 . 3 et 33 , 66 on remarque ici des espaces autour du point ou de la virgule.
j'ai essayé dans ce meme ordre d'idée un code qui m'a donné un résultat erroné;
pourrais je avoir votre aide svp.

16 réponses

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 15:14
Alors si tu veux faire cela, deux solutions:
- Vérifiez l'avant-avant-dernier (donc étendre la précedente technique)
- Changez de technique, et dire "quand je suis sur un carctère de ponctuation, vérifier autour si il y a des chiffres. continuer d'avancer tant que c'est un espace" (A faire à gauche et à droite).

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 15:58
En fait, si tu as plus d'un espace, et que tu ne peux en deviner le nombre, la 1ère technique est invalide et ne peut être utilisée.
Je te conseil donc la seconde méthode.

Fais toi une fonction qui prend la position de début, la position de fin, et la position courante, et qui dit si le caractère courant doit être imprimé ou non.
Il alors facile de "regarder" à gauche, puis à droite de ta position courante, pour détecter des caractères ayant une signification spéciale.

int isValid(const char* begin, const char* end, const char* pos);


A noter qu'il vaut mieux dans ce cas, récupérer les lignes une par une plutôt que carctère par caractères. Ou alors utiliser mmap.

________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée quand un post répond à votre question
3
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 17:02
Tu es conscient que ce n'est plus du C ? C'est du C++.

Ta logique était fausse. Il fallait utiliser "&& !withinDigit" et non "|| !withinDigit".
J'ai aussi apporté quelques améliorations, qui ne provoque plus de warnings:
#include <fstream>
#include <sstream>
#include 

namespace
{
  inline bool digitAtPos(size_t i, const std::string& str)
  {
    return (i != std::string::npos) && isdigit(str[i]);
  }

  bool withinDigit(const std::string& str, unsigned int pos)
  {
    unsigned int before = str.find_first_not_of(" \t\n", pos + 1);
    unsigned int after  = str.find_last_not_of (" \t\n", pos - 1);
    return digitAtPos(before, str) && digitAtPos(after, str);
  }
}

int main()
{
  std::ofstream out("out.txt", std::ios::out);
  std::ifstream in("in.txt");

  std::stringbuf strbuf;
  in.get(strbuf, EOF);
  std::string str = strbuf.str();

  const std::string toErase = ".;:,!?+-{}()"/";

  size_t pos = str.find_first_of(toErase, 0);

  //std::cout << str << std::endl;

  while (pos != std::string::npos)
  {
    if ((str[pos] != '.' || str[pos] != ',' || str[pos] != ':')
&& !withinDigit(str, pos))
      str.erase(str.begin() + pos);
    pos = str.find_first_of(toErase, pos + 1);
  }
  out << str;

  in.close();
  out.close();
  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
[color=green]Merci d'utiliser [i]Réponse acceptée[
3
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 13:54
en fait mon problème c'est de réécrire les nombres sans espaces, car je suis arrivée à les réécrire mais avec espaces
0

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

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 14:29
Peux-tu ajouter un exemple d'utilisation ? (Le fichier in.txt que tu utilises)

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 14:53
in:
1.1this is a test: 22 . 56

out:
1.1this is a test 22  56
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 14:59
Que veux-tu faire ? Tu n'es pas très clair...

Sachant que l'on a 22 . 56, tu cherches à obtenir quel résultat ?
- 22.56
- 22 56
- 2256
- 22 . 56

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 15:11
je veux obtenir 22.56
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 15:31
j'ai essayé d'étendre la précédente technique et j'ai ajouté ces instructions:
    
avant_avant_avant_avant = avant_avant_avant;
avant_avant_avant = avant_avant;
//après le if de la précédente technique	
else if  (isdigit(actuel) && (avant ' ') && (avant_avant'.'||avant_avant ==',' || avant_avant == ':') && (avant_avant_avant == ' ') && isdigit(avant_avant_avant_avant))
fprintf(stream1, "%c%c%c",avant_avant_avant_avant, avant_avant, actuel);


le résultat était:
out:
1.1this is a test 22  2.56
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 15:38
Comment feras-tu si tu as plus qu'un seul espace qui sépare un signe de ponctuation ?

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée quand un post répond à votre question
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 15:52
je ferai de meme, mais ça devient beaucoup plus complexe
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 16:44
svp Mr CptPingu, est ce que vous pouvez essayer ce code, il m'a donné un fichier vide, j'ai pas pu savoir la raison
#include <fstream>
#include <string>
#include <sstream>

namespace {
    inline bool digitAtPos(unsigned int i, const std::string& str)
    {
        return (i != std::string::npos) && isdigit(str[i]);
    }

    bool withinDigit(const std::string& str, unsigned int pos)
    {
        unsigned int before = str.find_first_not_of(" \t\n", pos +1);
        unsigned int after  = str.find_last_not_of (" \t\n", pos -1);
        return digitAtPos(before, str) && digitAtPos(after, str);
    }
}

int main()
{
    std::ofstream out("out", std::ios::out);
    std::ifstream in("in");

    std::stringbuf strbuf;
    in.get(strbuf, EOF);
    std::string str = strbuf.str();

    std::string toErase = ".;:,!?+-{}()"/";

    unsigned int pos = str.find_first_of(toErase, 0);

    while(pos != std::string::npos)
    {
        if(!(str[pos] == '.' || str[pos] == ',' || str[pos] == ':') || !withinDigit(str, pos))
            str.erase(str.begin()+pos);
        pos = str.find_first_of(toErase, pos +1);
    }
    out << str;

    in.close();
    out.close();
    return 0;
}
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 17:11
oui je sais que c'est du c++, mais franchement ce n'est pas mon travail, il ya quelqu'un qui m'a aidé à le faire,
et je ne sais pas quand utiliser le c et quand le c++
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
30 juin 2010 à 17:14
Je me suis douté que ce n'était pas de toi.

On choisit un langage par préférence. Si tu préfères le C, tu fais du C. Si tu veux faire du C++, tu fais du C++. Personnellement je fais essentiellement du C++, mais ça reste un choix personnel.

________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
[color=green]Merci d'utiliser [i]Réponse acceptée[
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 17:18
oui c'est sur un débutant ne peut pas faire ceci;
merci bien pour tous vos conseils et aides.
0
cs_mervat Messages postés 90 Date d'inscription samedi 5 juin 2010 Statut Membre Dernière intervention 6 mars 2015
30 juin 2010 à 18:23
c'est vrai que ce programme permet d'afficher les caractères de ponctuation entre 2 chiffres mais il ne me permet pas d'éliminer les espaces pour avoir dans le résultat final 22.56 aulieu de 22 . 56
0
Rejoignez-nous