8 Stimmen

Wie kann man eine Textdatei in Wörter aufteilen?

Ich arbeite an einer Aufgabe, bei der ich eine Datei lesen und die Anzahl der Zeilen und gleichzeitig die Wörter in der Datei zählen soll. Ich habe eine Kombination aus getline und strtok innerhalb einer while-Schleife ausprobiert, was nicht funktioniert hat.

file:example.txt (die zu lesende Datei).

Hallo, hallo, was für eine angenehme Überraschung.
Willkommen an diesem Ort.
Ich wünsche Ihnen einen angenehmen Aufenthalt hier.
(3 Zeilen und einige Wörter).

Readfile.cpp

#include <iostream>
#include <fstream>
#include<string>
using namespace std;
int main()
{
  ifstream in("example.txt");
  int count = 0;

  if(!in)
  {
    cout << "Cannot open input file.\n";
    return 1;
  }

  char str[255];
  string tok;
  char * t2;

  while(in)
  {
    in.getline(str, 255);
    in>>tok;
    char *dup = strdup(tok.c_str());
    do 
    {
        t2 = strtok(dup," ");
    }while(t2 != NULL);
    cout<<t2<<endl;
    free (dup);
    count++;
  }
  in.close();
  cout<<count;
  return 0;
}

0 Stimmen

Sie müssen mehr sagen als "hat nicht funktioniert". Sagen Sie uns, welcher Fehler auftritt oder was genau Ihr Programm anders macht, als Sie erwarten, und stellen Sie dann eine konkrete Frage. Wir werden Ihre Hausaufgaben nicht für Sie debuggen oder neu schreiben.

17 Stimmen

Wie wäre es mit einigen der folgenden Beispiele? codeproject.com/KB/rezepte/Tokenizer.aspx Sie sind sehr effizient und etwas elegant. Die String Toolkit Library macht komplexe String-Verarbeitung in C++ einfach und leicht.

5voto

Rocco Lampone Punkte 141

Ich habe es gerade richtig gemacht!! Habe gerade allen unnötigen Code entfernt.

int main()
{    
    ifstream in("example.txt");
    int LineCount = 0;
    char* str = new char[500];

    while(in)
    {
        LineCount++;
        in.getline(str, 255);
        char * tempPtr = strtok(str," ");
        while(tempPtr)
        {
            AddWord(tempPtr, LineCount);
            tempPtr = strtok(NULL," ,.");
        }
    }
    in.close();
    delete [] str;
    cout<<"Total No of lines:"<<LineCount<<endl;
    showData();

    return 0;
}

Die ursprüngliche Problemstellung war übrigens, ein Indexprogramm zu erstellen, das eine Benutzerdatei akzeptiert und einen Zeilenindex aller Wörter erstellt.

0 Stimmen

Bitte verwenden Sie nicht strtok. Das wird Ihnen zum Verhängnis, sobald Sie Multithreading-Code schreiben müssen. Ein guter Ersatz in Standard-C++ ist std::istringstream.

4voto

Tom Punkte 10491

Ich habe nicht versucht, dies zu kompilieren, aber hier ist eine Alternative, die fast so einfach ist wie die Verwendung von Boost, aber ohne die zusätzliche Abhängigkeit.

#include <iostream>
#include <sstream>
#include <string>

int main() {
  std::string line;
  while (std::getline(std::cin, line)) {
    std::istringstream linestream(line);
    std::string word;
    while (linestream >> word) {
      std::cout << word << "\n";
    }
  }
  return 0;
 }

0 Stimmen

+1 So würde ich es machen. Jetzt nur noch die Zähler einfügen und fertig.

0voto

Reed Copsey Punkte 536986

Versuchen Sie, Ihre cout<<t2<<end; Anweisung in Ihre while-Schleife ein.

Damit sollte Ihr Code grundsätzlich funktionieren.

Sie möchten vielleicht sehen dieser ähnliche Beitrag für andere Ansätze.

0voto

X-Istence Punkte 15834

Solche Beispiele sind überall im Internet zu finden. Hier ist ein Programm zum Zählen von Wörtern, das ich in der High School geschrieben habe. Verwenden Sie es als Ausgangspunkt. Andere Dinge, auf die ich hinweisen möchte, sind:

std::stringstream :Sie std::getline die gesamte Zeile, dann verwenden Sie std::stringstream, um sie in kleinere Stücke zu zerhacken und zu tokenisieren. Sie können die gesamte Zeile mit std::getline holen und in einen std::string eingeben, den Sie dann an std::stringstream übergeben können.

Noch einmal, dies ist nur ein Beispiel und wird nicht genau das tun, was Sie wollen, müssen Sie es selbst ändern, damit es das tut, was Sie tun wollen!

#include <iostream>
#include <map>
#include <string>
#include <cmath>
#include <fstream>

// Global variables
        std::map<std::string, int> wordcount;
        unsigned int numcount;

void addEntry (std::string &entry) {
        wordcount[entry]++;
        numcount++;
        return;
}

void returnCount () {
        double percentage = numcount * 0.01;
        percentage = floor(percentage + 0.5f);

        std::map<std::string, int>::iterator Iter;

        for (Iter = wordcount.begin(); Iter != wordcount.end(); ++Iter) {
                if ((*Iter).second > percentage) {
                        std::cout << (*Iter).first << " used " << (*Iter).second << " times" << std::endl;
                }
        }

}

int main(int argc, char *argv[]) {
        if (argc != 2) {
                std::cerr << "Please call the program like follows: \n\t" << argv[0] 
                        << " <file name>" << std::endl;
                return 1;
        }

        std::string data;

        std::ifstream fileRead;
        fileRead.open(argv[1]);
        while (fileRead >> data) {
                addEntry(data);
        }
        std::cout << "Total words in this file: " << numcount << std::endl;
        std::cout << "Words that are 1% of the file: " << std::endl;
        returnCount();
}

0 Stimmen

Hallo, danke, Blorgbeard, Reed und X-Istence für die prompten Antworten. Ich muss nicht nur die Zeile analysieren, sondern auch die Zeilennummern im Auge behalten. Das Problem besteht darin, eine Liste von Wörtern mit den Zeilennummern zu erstellen, in denen sie vorkommen.

0 Stimmen

Ravi: Mit dem Code, den ich dir gerade gegeben habe, bist du schon halb am Ziel. Wir sind nicht hier, um Ihre Hausaufgaben für Sie zu erledigen!

0 Stimmen

Oh nein! Das war nicht meine Absicht. Ich habe nur mit dem ersten Teil Probleme. Sobald das behoben ist, werde ich den Rest selbst erledigen.

0voto

Klaim Punkte 63705

Wenn Sie Boost-Bibliotheken verwenden können, würde ich vorschlagen, dass Sie boost::tokenizer :

Das Paket boost Tokenizer bietet eine flexible und einfach zu bedienende Methode zum Aufbrechen einer Zeichenkette oder einer anderen Zeichen Zeichenfolge in eine Reihe von Token zu zerlegen. Nachfolgend ein einfaches Beispiel, das eine Phrase in Wörter auflöst.

// simple_example_1.cpp
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>

int main(){
   using namespace std;
   using namespace boost;
   string s = "This is,  a test";
   tokenizer<> tok(s);
   for(tokenizer<>::iterator beg=tok.begin();beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X