2015-07-06 4 views
0

Это мой код, который учитывает вхождения определенной строки в файл.Подсчет событий в файле в C++

#include <iostream> 
#include <string>  

int frequency(std::string s, std::string file_name){ 

    std::ifstream file; 
    std::string word; 
    int count = 0; 

    try{ 
     file.open(file_name); 

     while(file>>word){ 
      if(s.compare(word) == 0) ++count; 
     } 

     file.close(); 
    }catch(std::ifstream::failure e){ 
     //std::cout<<e<<std::endl; 
    } 
    return count; 
} 

//=============================================== 
int main() { 

    std::string file_name, word; 

    std::cout << "Enter file name.." << '\n'; 
    std::cout << "Enter word.. " << '\n'; 

    std::cin >> file_name >> word; 

    int count = frequency(word, file_name); 

    std::cout << "Occurrences of " << word << ": " << count; 

    return 0; 
} 

Файл указан в корневом каталоге проекта. Проблема в том, что я получаю 0 для подсчета любого слова.

+0

Вступление слов .... есть ли каждое слово, ограниченное пробелами? этот код будет работать только для поиска независимых строк, например, он не найдет слово 'fun' в' funds' – Catalyst

+0

Yup, это поведение, я хочу, но это даже не так. – Moffet

+0

Вы проверили, правильно ли открыт входной файл? Почему у вас есть обработчик исключений? –

ответ

2

I изменено с file.open(file_name); по file.open(file_name.c_str()); и он работал нормально.

$ cat file.txt 
hello 
good bye 

$ a.out 
Enter file name.. 
Enter word.. 
file.txt 
hello 
Occurances of hello: 1 

ifstream берет с-строку в качестве входного сигнала, а не строка. Для того, чтобы поймать убедитесь, что файл открыт перед чтением с:

if (file.is_open()){ 
    ... do stuff.... 
else 
    ... error 
+1

Начиная с C++ 11, 'ifstream' принимает параметр' string'. В противном случае, если OP использует старый компилятор, это привело бы к ошибке времени компиляции. – Ferruccio

+0

@Ferruccio хорошо знать. В C++ 11 я очень мало, но это приятное изменение. Я опубликовал этот ответ, потому что после скопирования копии кода OP я сделал это одно изменение, и оно сработало ... go figure. Хорошо, что и я добавил '#include '. – Matt

0

С несколькими небольшими исправлениями ваш код будет делать эту работу, а именно файл цикла чтения можно модифицировать, чтобы, во-первых прочитать всю строку, а затем прочитать каждый string содержащийся в нем отдельно:

int frequency(std::string s, std::string file_name) { 

    std::ifstream file(file_name.c_str()); 
    // check if file successfully open 
    if (!file) cerr << "Can't open input file!\n"; 

    int count = 0; 
    try{ 

     // extract all lines 
     std::string line; 
     while(getline(file, line)) { 

      stringstream ss(line); 
      string word; 

      // extract all words separated by white space 
      while (ss >> word) { 

       // compare with wanted 
       if(s == word) ++count; 
      } 
     } 

    }catch(std::exception& e){ 

     // std::cout << e.what() << std::endl; 

    } 
    return count; 
} 

Несколько заметок:

  • вам не нужно явно закрывать поток файлов, это делается автоматически в конце, так как file является локальной переменной в функции.

  • try - catch блок избыточен, если вы используете его только для проверки состояния потока. Вы можете сделать это с помощью одной строки, как указано в ответе.

  • Это хорошая практика для имени файла c - строка стиля (заканчивается на '\ 0'). Функция члена потока c_str() выполняет преобразование.

  • вы можете открыть файл в определении потока и пропустить строку, содержащую функцию члена потока open().

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