2010-09-15 5 views
4

J'ai parcouru mon livre et essayé d'écrire du code pour lire un fichier texte et en extraire les mots, par un, donc je peux les mettre dans l'ordre alphabétique et tenir compte du nombre de mots utilisés et beaucoup de mots ont été utilisés. Je n'arrive pas à faire fonctionner correctement ma fonction GetNextWord() et ça me rend fou.C++ Lecture de mots à partir d'un fichier texte, mot à mot ou caractère par caractère

Je dois lire les mots, un par un, et convertir chaque lettre en minuscule si elle est en majuscule. Ce que je sais faire, et je l'ai fait avec succès. Il s'agit simplement de trouver le mot caractère par caractère et de le mettre dans une chaîne qui me retient.

Ceci est mon essai le plus récent: Toute aide serait incroyable ou un lien vers un tutoriel sur la façon de lire un fichier d'entrée mot par mot. (Word étant caractères alpha az et '(ne pas) terminée par un espace, virgule,,;,:, ect ....

void GetNextWord() 
{ 
    string word = ""; 
    char c; 

    while(inFile.get(c)) 
    { 
     while(c > 64 && c < 123 || c == 39) 
     { 
      if((isupper(c))) 
      { 
       c = (tolower(c)); 
      } 
      word = word + c; 
     } 
     outFile << word; 
    } 
} 
+0

La sortie est-elle le problème? –

+0

De plus, mettez des parenthèses dans vos conditions pour les définir clairement. –

+5

NE PAS utiliser de nombres magiques, ils ne sont pas portables. Utilisez 'A' ou 'Z' ou tout ce qui est censé être. –

Répondre

3

Votre logique est erronée. La boucle interne s'exécute tant que c ne change pas, et rien ne change c. Pourquoi avez-vous deux boucles de toute façon? Je pense que vous pourriez être confus quant à savoir si cette fonction est censée lire le mot suivant ou tous les mots. Essayez de séparer ces préoccupations, mettez-les dans différentes fonctions (dont l'une appelle l'autre).Je trouve qu'il est plus facile d'aborder ces problèmes dans un ordre de haut en bas:

while(inFile.good()) { 
    std::string word = GetNextWord(inFile); 
    if(!word.empty()) 
    std::cout << word << std::endl; 
} 

maintenant remplir les lacunes en définissant GetNextWord() pour lire tout jusqu'à la prochaine limite de mot.

+0

Je vais essayer et rapporter avec mes résultats, merci – MSwezey

+0

Merci! fonctionne comme un charme! – MSwezey

8

Vous pouvez lire le mot de fichier par mot en utilisant l'opérateur >> . par exemple, voir ce lien:. http://www.daniweb.com/forums/thread30942.html

J'extrairez leur exemple ici:

ifstream in ("somefile"); 
vector<string> words; 
string word 

if (!in) 
    return; 

while (in>> word) 
    words.push_back (word); 
+1

Mais cet opérateur utilise une définition différente de ce qu'est un mot de ce qui a été demandé. – sbi

0

Personnellement j'aime lire en entrée avec std::getline(std::istream&, std::string&) (dans l'en-tête <string>, mais vous aurez bien sûr besoin aussi #include un en-tête de flux).

Cette fonction est interrompue sur le retour à la ligne, qui correspond aux espaces correspondant à la définition de votre problème. Mais ce n'est pas la réponse entière à votre question. Après avoir lu dans la ligne de texte, vous devrez utiliser string operations ou des algorithmes standard pour casser la chaîne en mots. Ou vous pourriez faire une boucle sur la corde à la main.

Les tripes serait quelque chose comme:

std::string buffer; 
while (std::getline(std::cin, buffer) { 
// break each line into words, according to problem spec 
} 
+0

Cela pourrait être problématique s'il y a des mots coupés dans le texte. –

+0

Un mot coupé comme "back-scatter" n'a pas d'importance, car la spécification du problème définit si elle compte pour un ou deux mots. Cependant, si je comprends correctement Space_C0wb0y, les mots qui sont coupés pour continuer sur la ligne suivante nécessiteraient plus de logique que ce que j'ai montré. Étant donné que ce programme ressemble beaucoup à des devoirs, je doute que ce soit une entrée valide, mais si c'est le cas, alors il serait nécessaire de gérer une telle entrée. –

0

J'utilise

// str is a string that holds the line of data from ifs- the text file. 
// str holds the words to be split, res the vector to store them in. 
while(getline(ifs, str)) 
    split(str, res); 


void split(const string& str, vector<string>& vec) 
{ 
    typedef unsigned int uint; 

    const string::size_type size(str.size()); 
    uint start(0); 
    uint range(0); 

/* Explanation: 
    * Range - Length of the word to be extracted without spaces. 
    * start - Start of next word. During initialization, starts at space 0. 
    * 
    * Runs until it encounters a ' ', then splits the string with a substr() function, 
    * as well as making sure that all characters are lower-case (without wasting time 
    * to check if they already are, as I feel a char-by-char check for upper-case takes 
    * just as much time as lowering them all anyway.          
*/ 
    for(uint i(0); i < size; ++i) 
    { 
     if(isspace(str[i])) 
     { 
      vec.push_back(toLower(str.substr(start, range + 1))); 
      start = i + 1; 
      range = 0; 
     } else 
      ++range; 
    } 
    vec.push_back(toLower(str.substr(start, range))); 
} 

Je ne sais pas ce qui est particulièrement utile pour vous, mais je vais essayer. La fonction toLower est une fonction rapide qui utilise simplement la fonction :: toLower(). Ceci lit chaque caractère jusqu'à un espace, puis le place dans un vecteur. Je ne suis pas tout à fait sûr de ce que vous voulez dire par char de char.

Voulez-vous extraire un caractère de mot à la fois? Ou voulez-vous vérifier chaque personnage au fur et à mesure? Ou voulez-vous dire que vous voulez extraire un mot, finir, puis revenir? Si c'est le cas, je voudrais 1) recommander un vecteur de toute façon, et 2) faites le moi savoir afin que je puisse refactoriser le code.

+0

mon plan d'origine était de lire en un mot, char par char à la fois, et quand il frappe un espace ou une ponctuation, il arrête d'obtenir le mot, transforme tous ces caractères en une chaîne et envoie cette chaîne à mon autre fonction En traitement. tournant tous les majuscules en minuscules. IE "Ne pas" deviendrait "ne pas". – MSwezey

0

Que va mettre fin à votre boucle interne si c == 'a'? La valeur ASCII pour 'a' est 97.

+0

si c == a alors son ne va pas terminer la boucle interne. la boucle interne se termine si le caractère n'est pas A-Z, a-z, et ' – MSwezey

Questions connexes