C++ match string in file and get line number

我怕爱的太早我们不能终老 提交于 2019-12-20 04:18:53

问题


I have a file with the top 1000 baby names. I want to ask the user for a name...search the file...and tell the user what rank that name is for boy names and what rank for girl names. If it isn't in boy names or girl names, it tells the user it's not among the popular names for that gender.

The file is laid out like this:

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

Desired output for input Michael would be:

Michael is 2nd most popular among boy names.

If Michael is not in girl names it should say:

Michael is not among the most popular girl names

Though if it was, it would say:

Micheal is (rank) among girl names

The code I have so far is below.. I can't seem to figure it out. Thanks for any help.

#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();
}

回答1:


First off, looks like you're trying to open a rich text format file (.rtf). This won't work, as the file doesn't contains only text but also other data (http://en.wikipedia.org/wiki/Rich_Text_Format).

Then in your code: while(getline(input,line1)) reads a line every iteration. That's fine, but inside the loop yo do input >> rank >> boy_name >> girl_name; which continues to read in next line

You want to work with line1. You can construct a stringstream from line1, then read the names from it:

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

That and what Beta wrote in his answer; you "give up" in each line where names don't match.




回答2:


You are conceding defeat ("X is not among the popular Y names") before you have finished scanning the list. A good simple way (if not the most efficient) is to remember the ranks until the end of the list, before announcing that there was no match. Something like this:

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";
}



回答3:


You could definitely do some more analysis and isolation of your problem before posting a question.

For instance, you are in a loop calling getline, which reads a line of text into line1 out of your input. But then you do nothing with line1. You use iostream operators to read in the fields of data on the line after it. So this is going to effectively skip every other line. It would be easy to tell that if you just put in a debugging sanity check in your loop like:

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

Then you could formulate your question as "why am I only getting every other line". Which would be easier for people to answer, but you might also have a chance at answering it yourself.

Another potential problem is if you have a .RTF "Rich Text" file instead of a plain-ol text file. It may have extra junk in it that's confusing your code. Homework assignments would not typically give you wacky formats to deal with, because that's a whole new can of worms.



来源:https://stackoverflow.com/questions/7779469/c-match-string-in-file-and-get-line-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!