C ++ сопоставить строку в файле и получить номер строки - PullRequest
1 голос
/ 15 октября 2011

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

Файл выложен так:

Rank Boy-Names Girl-Names
1    Jacob     Emily
2    Michael   Emma
.
.
.

Желаемый выход для ввода Michael будет:

Майкл занимает второе место по популярности среди мальчиков.

Если Майкла нет в именах девушек, он должен сказать:

Майкл не входит в число самых популярных имен девушек

Хотя, если бы это было так, он сказал бы:

Майкл (ранг) среди имен девушек

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

#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
void find_name(string name);

int main(int argc, char **argv)
{
    string name;
    cout << "Please enter a baby name to search for:\n";
    cin >> name;
    /*while(!(cin>>name))
    {
        cout << "Please enter a baby name to search for:\n";
        cin >> name;
    }*/
    find_name(name);

    cin.get();
    cin.get();
    return 0;
}

void find_name(string name)
{
    ifstream input;
    int line = 0;
    string line1 = " ";
    int rank;
    string boy_name = "";
    string girl_name = "";
    input.open("/<path>/babynames2004.rtf");
    if (!input)
    {
        cout << "Unable to open file\n";
        exit(1);
    }

    while(input.good())
    {
        while(getline(input,line1))
        {
            input >> rank >> boy_name >> girl_name;
            if (boy_name == name)
            {
                cout << name << " is ranked " << rank << " among boy names\n";
            }
            else
            {
                cout << name << " is not among the popular boy names\n";
            }
            if (girl_name == name)
            {
                cout << name << " is ranked " << rank << " among girl names\n"; 
            }
            else
            {
                cout << name << " is not among the popular girl names\n";
            }
        }
    }
    input.close();
}

Ответы [ 3 ]

3 голосов
/ 15 октября 2011

Вы признаете поражение («X не входит в число популярных имен Y») до того, как закончите сканирование списка. Хороший простой способ (если не самый эффективный) - помнить ряды до конца списка, прежде чем объявить, что не было совпадений. Примерно так:

bool boyrank = false, girlrank = false;

while(getline(input,line1))
{
  input >> rank >> boy_name >> girl_name;
  if (boy_name == name)
    {
      cout << name << " is ranked " << rank << " among boy names\n";
      boyrank = true;
    }

  if (girl_name == name)
    {
      cout << name << " is ranked " << rank << " among girl names\n";
      girlrank = true;
    }
}

if(boyrank == false)
{
  cout << name << " is not among the popular boy names\n";
}
if(girlrank == false)
{
  cout << name << " is not among the popular girl names\n";
}
2 голосов
/ 15 октября 2011

Вы можете определенно проанализировать и изолировать свою проблему, прежде чем отправлять вопрос.

Например, вы находитесь в цикле, вызывающем getline, который читает строку текста в line1 из вашего input. Но тогда вы ничего не делаете с line1. Вы используете операторы iostream для чтения в полях данных в строке после него. Так что это будет эффективно пропустить все остальные строки. Было бы легко сказать, что если вы просто включите проверку исправности в вашем цикле, например:

cout << "rank = " << rank << " boy_name = " << boy_name << 
        " girl_name = " << girl_name << endl;

Тогда вы могли бы сформулировать свой вопрос как "почему я получаю только все остальные строки". На что людям было бы легче ответить, но у вас также может быть шанс ответить на него самостоятельно.

Другая потенциальная проблема - если у вас есть файл RTF «Rich Text» вместо обычного текстового файла. В нем может быть дополнительный мусор, который запутывает ваш код. Домашние задания обычно не дают вам дурацких форматов для работы, потому что это совершенно новая банка червей.

1 голос
/ 15 октября 2011

Во-первых, похоже, вы пытаетесь открыть файл в расширенном текстовом формате (.rtf).Это не сработает, так как файл содержит не только текст, но и другие данные (http://en.wikipedia.org/wiki/Rich_Text_Format).

Затем в вашем коде: while(getline(input,line1)) читает строку каждую итерацию. Это нормально, но внутри циклаyo do input >> rank >> boy_name >> girl_name;, который продолжает читать следующую строку

Вы хотите работать с line1. Вы можете создать поток строк из строки1, а затем прочитать имена из нее:

stringstream ss(line1):
ss >> rank >> boy_name >> girl_name;

Это и то, что Бета написала в своем ответе: вы «сдаетесь» в каждой строке, где имена не совпадают.

...