éliminer les caractères de ponctuation d'un texte [Résolu]

Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
- - Dernière réponse : cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
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.
Afficher la suite 

Votre réponse

16 réponses

Meilleure réponse
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
3
Merci
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]

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
3
Merci
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

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
3
Merci
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[

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
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
Commenter la réponse de cs_mervat
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
0
Merci
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]
Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
in:
1.1this is a test: 22 . 56

out:
1.1this is a test 22  56
Commenter la réponse de cs_mervat
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
0
Merci
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]
Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
je veux obtenir 22.56
Commenter la réponse de cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
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
Commenter la réponse de cs_mervat
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
0
Merci
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
Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
je ferai de meme, mais ça devient beaucoup plus complexe
Commenter la réponse de cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
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;
}
Commenter la réponse de cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
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++
Commenter la réponse de cs_mervat
Messages postés
3831
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
30 janvier 2019
162
0
Merci
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[
Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
oui c'est sur un débutant ne peut pas faire ceci;
merci bien pour tous vos conseils et aides.
Commenter la réponse de cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
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
Commenter la réponse de cs_mervat

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.