Правильное место в гнездах, чтобы положить кут - PullRequest
1 голос
/ 06 мая 2011

РЕДАКТИРОВАТЬ: изменен на логический флаг, но все еще печатает больше, чем следует:

string line; // a string to hold the current line
while(getline(myFile,line)) {
bool old_count = false; // to help determine whether the line has been output yet
for (unsigned int i = 0; i < line.length(); i++) {
    string test = line.substr( i, targ_length );
    if ( strcmp(word.c_str(),test.c_str()) == 0  ) {
        count++;
        if ( !old_count ); {
        cout << line_num << " : " << line << endl;
        } // end if
        old_count=true;
    } // end if     
} //end for
line_num++;
} // end while

/ конец редактирования

У меня есть задание написать программу для поиска слова в текстовом файле. У меня он работает отлично, за исключением того, что он должен печатать каждую строку, в которой находится слово, и моя программа будет печатать одну и ту же строку несколько раз, если слово появляется несколько раз в строке. Мне нужно, чтобы напечатать строку только один раз. Я пытался переместить if (count! = Old_count) по разным местам, но не удача и запутался. Мой код ниже. Спасибо за любую помощь!

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;

/* minimum required number of parameters */
#define MIN_REQUIRED 3

/* display usage */
int help() {
printf("Proper usage: findWord <word> <file>\n");
printf("where\n");
printf("    <word> is a sequence of non-whitespace characters\n");
printf("    <file> is the file in which to search for the word\n");
printf("example: findWord the test.txt\n");
return 1;
}

/*
 * Program that searches for occurrences of given word within a given file
 * @return 0 (default for a main method)
 */
int main(int argc, char *argv[]) {

if (argc < MIN_REQUIRED) {
return help();
} // end if

string word = argv[1]; // the word to be searched for
string file_name = argv[2]; // the name of the file to be read

ifstream myFile(file_name.c_str()); // read the file
if (! myFile) {
cerr << "File '" << file_name << "' could not be opened" << endl;
return -1;
} // end if

cout << "Searching for '" << word << "' in file '" << file_name << "'\n";

int targ_length = word.length(); // the legnth of the string we're searching for

int count = 0; // running count of instances of word found
int line_num = 1; // number of current line

string line; // a string to hold the current line
while(getline(myFile,line)) {
int old_count = count; // to help determine whether the line has been output yet
for (unsigned int i = 0; i < line.length(); i++) {
    string test = line.substr( i, targ_length );
    if ( strcmp(word.c_str(),test.c_str()) == 0  ) {
        count++;
    } // end if
    if ( old_count != count ); {
        cout << line_num << " : " << line << endl;
    } // end if     
} //end for
line_num++;
} // end while

cout << "# occurrences of '" << word <<" ' = " << count << endl;

return 0;
}

Ответы [ 4 ]

1 голос
/ 06 мая 2011

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

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

while(getline(myFile,line)) {
    for (unsigned int i = 0; i < line.length(); i++) {
        string test = line.substr( i, targ_length );
        if ( strcmp(word.c_str(),test.c_str()) == 0  ) {
            cout << line_num << " : " << line << endl;
            break; // exit inner for loop as soon as the word is found
        } // end if     
    } //end for
    line_num++;
} // end while
1 голос
/ 06 мая 2011

Используйте ассоциативный контейнер, такой как std::set, который будет содержать значение строки только один раз, даже если вы пытаетесь вставить его несколько раз.

Кроме того, ваш код полон некоторых крайне бессмысленных C-измов.

if ( strcmp(word.c_str(),test.c_str()) == 0  ) {

должно быть

if (word == test )) {

#define должно быть static const int, printf заменено на cout.

1 голос
/ 06 мая 2011

Попробуйте изменить флаг int для флага bool, например:

while(getline(myFile,line)) {
bool old_count = false; // to help determine whether the line has been output yet
bool second_flag = false;
for (unsigned int i = 0; i < line.length(); i++) {
    string test = line.substr( i, targ_length );
    if ( strcmp(word.c_str(),test.c_str()) == 0  ) {
        old_count = true;
    } // end if
    if ( old_count && !second_flag ){
        cout << line_num << " : " << line << endl;
        second_flag = true;
    } // end if     
} //end for
line_num++;
} // end while
0 голосов
/ 06 мая 2011

Вы используете не тот инструмент для работы.Вместо вызова substr () для каждого символа в текущей строке используйте функцию, которая находит нужную строку в строке.Похоже, что strstr () может быть то, что вам нужно.http://www.cplusplus.com/reference/clibrary/cstring/strstr/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...