C ++ Чтение словами из текстового файла, слово за словом или символ с символом - PullRequest
4 голосов
/ 15 сентября 2010

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

Мне нужно прочитать слова по одному и преобразовать каждую букву в нижний регистр, если это верхний регистр. Который я знаю, как это сделать, и сделал это успешно. Это просто получение слова символ за символом и помещение его в строку, которая держит меня.

Это моя последняя попытка: любая справка была бы удивительной или ссылка на учебник о том, как читать слово из слова во входном файле. (Слово представляет собой буквенные символы a-z и '(не), оканчивающиеся пробелом, запятой, точкой,;,:, 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;
    }
}

Ответы [ 5 ]

8 голосов
/ 15 сентября 2010

Слово за словом можно прочитать с помощью оператора >>.Например, смотрите эту ссылку: http://www.daniweb.com/forums/thread30942.html.

Я привел их пример здесь:

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

if ( !in )
  return;

while ( in>> word )
  words.push_back ( word );
3 голосов
/ 15 сентября 2010

Ваша логика неверна. Внутренний цикл работает до тех пор, пока c не изменится, и в нем нет ничего, что изменило бы c.

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

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

Теперь заполните пробелы, определив GetNextWord(), чтобы прочитать все до следующей границы слова.

0 голосов
/ 15 сентября 2010

Что прервет ваш внутренний цикл, если c == 'a'? Значение ASCII для 'a' равно 97.

0 голосов
/ 15 сентября 2010

Я использую

// 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)) );
}

Я не уверен, что это особенно полезно для вас, но я попробую. Функция toLower - это быстрая функция, которая просто использует функцию :: toLower (). Это читает каждый символ до пробела, а затем вставляет его в вектор. Я не совсем уверен, что ты имеешь в виду под char за char.

Хотите извлечь символ слова по времени? Или вы хотите проверить каждого персонажа по ходу дела? Или вы имеете в виду, что хотите извлечь одно слово, закончить, а затем вернуться? Если это так, я бы все равно 1) порекомендовал вектор и 2) дал мне знать, чтобы я мог реорганизовать код.

0 голосов
/ 15 сентября 2010

Лично мне нравится читать при вводе std::getline(std::istream&, std::string&) (в заголовке <string>, но вам, конечно, также потребуется #include заголовок потока).

Эта функция переносится на новую строку, которая является пробелом по определению вашей проблемы. Но это еще не весь ответ на ваш вопрос. После прочтения строки текста вам понадобится использовать строковые операции или стандартные алгоритмы, чтобы разбить строку на слова. Или вы можете перебрать строку вручную.

Кишки будут выглядеть примерно так:

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