2015-12-06 2 views
0

Я пытаюсь прочитать из текстового файла стихотворение, содержащее запятые, пробелы, периоды и символ новой строки. Я пытаюсь использовать getline для чтения в каждом отдельном слове. Я не хочу читать какие-либо запятые, пробелы, периоды или символ новой строки. Когда я читаю в каждом слове, я заглаживаю каждую букву, а затем вызываю свою функцию вставки, чтобы вставить каждое слово в двоичное дерево поиска в виде отдельного узла. Я не знаю, как лучше всего отделить каждое слово. Я был в состоянии отделить каждое слово пробелами, но запятые, точки и символы новой строки продолжают считываться вЧтение только букв из текстового файла

Вот мой текстовый файл:.

Розы красные, фиалки синие, Структуры данных является лучшим, Вы и я оба знаем, что это правда.

код, я использую это:

string inputFile; 
    cout << "What is the name of the text file?"; 
    cin >> inputFile; 

    ifstream fin; 
    fin.open(inputFile); 

    //Input once 
    string input; 
    getline(fin, input, ' '); 
    for (int i = 0; i < input.length(); i++) 
    { 
     input[i] = toupper(input[i]); 
    } 
    //check for duplicates 
    if (tree.Find(input, tree.Current, tree.Parent) == true) 
    { 
     tree.Insert(input); 
     countNodes++; 
     countHeight = tree.Height(tree.Root); 
    } 

В основном я использую GetLine (плавник, вход, ' «), чтобы прочитать в моем входе.

+0

Вы можете использовать 'getline (fin, input, '\ n');' для захвата каждой строки. А затем ** разобрать ** строку для слов. Чтобы проанализировать слово, вы можете использовать функцию 'find_first_of' member' std :: string'. –

+0

Есть ли способ решить эту проблему без использования внешних классов? Я студент, и мы не должны это делать. –

+1

Вы уже используете функцию 'getline' и класс' std :: string'. –

ответ

1

Я смог найти решение. Я смог прочитать всю строку кода в переменной строке, затем я искал каждую букву слова и только сохранял то, что было письмом, и я записал это в слово. Затем я смог вызвать функцию вставки для вставки узел в мое дерево.

const int MAXWORDSIZE = 50; 
    const int MAXLINESIZE = 1000; 
    char word[MAXWORDSIZE], line[MAXLINESIZE]; 
    int lineIdx, wordIdx, lineLength; 
    //get a line 
    fin.getline(line, MAXLINESIZE - 1); 
    lineLength = strlen(line); 
    while (fin) 
    { 
     for (int lineIdx = 0; lineIdx < lineLength;) 
     { 
      //skip over non-alphas, and check for end of line null terminator 
      while (!isalpha(line[lineIdx]) && line[lineIdx] != '\0') 
       ++lineIdx; 

      //make sure not at the end of the line 
      if (line[lineIdx] != '\0') 
      { 
       //copy alphas to word c-string 
       wordIdx = 0; 
       while (isalpha(line[lineIdx])) 
       { 
        word[wordIdx] = toupper(line[lineIdx]); 
        wordIdx++; 
        lineIdx++; 
       } 
       //make it a c-string with the null terminator 
       word[wordIdx] = '\0'; 

       //THIS IS WHERE YOU WOULD INSERT INTO THE BST OR INCREMENT FREQUENCY COUNTER IN THE NODE 
       if (tree.Find(word) == false) 
       { 
        tree.Insert(word); 
        totalNodes++; 
        //output word 
        //cout << word << endl; 
       } 
       else 
       { 
        tree.Counter(); 
       } 
      } 
0

Вы можете сделать пользовательскую функцию getline для нескольких разделителей:

std::istream &getline(std::istream &is, std::string &str, std::string const& delims) 
{ 
    str.clear(); 

    // the 3rd parameter type and the condition part on the right side of && 
    // should be all that differs from std::getline 
    for(char c; is.get(c) && delims.find(c) == std::string::npos;) 
     str.push_back(c); 

    return is; 
} 

И использовать:

getline(fin, input, " \n,."); 
0

Это хорошее время для техники я разместил несколько раз, прежде чем: определите грань ctype, которая обрабатывает все, кроме букв, как пробел (в поисках imbue будет показано несколько примеров).

Оттуда, это вопрос std::transform с istream_iterator с на входной стороне, в std::set на выходе, и лямбда с заглавной буквы.

0

Вы можете использовать std::regex, чтобы выбрать ваши маркеры

В зависимости от размера вашего файла вы можете прочитать либо построчно полностью или в std::string.

Для read the file вы можете использовать:

std::ifstream t("file.txt"); 
std::string sin((std::istreambuf_iterator<char>(t)), 
       std::istreambuf_iterator<char>()); 

и это будет делать сращивание для пространства разделены строки.

std::regex word_regex(",\\s]+"); 
auto what = 
    std::sregex_iterator(sin.begin(), sin.end(), word_regex); 
auto wend = std::sregex_iterator(); 

std::vector<std::string> v; 
for (;what!=wend ; wend) { 
    std::smatch match = *what; 
    V.push_back(match.str()); 
} 

Я думаю, что для разделения лексем разделены либо, пробел или новая строка, вы должны использовать это регулярное выражение: (,| \n|)[[:alpha:]].+. Я еще не тестировал, и вам может понадобиться проверить это.

Смежные вопросы