C ++匹配文件中的字符串并获取行号

时间:2011-10-15 17:36:57

标签: c++ iostream string-matching

我有一个包含前1000个婴儿名字的文件。我想问用户一个名字......搜索文件...并告诉用户该名字是男孩名字的等级以及女孩名字的等级。如果它不是男孩名字或女孩名字,它告诉用户它不属于该性别的流行名称。

文件的布局如下:

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

输入Michael的所需输出为:

  

迈克尔在男孩名字中排名第二。

如果迈克尔不在女孩的名字中,那么应该说:

  

迈克尔不是最受欢迎的女孩名字之一

虽然如果是,但它会说:

  

Micheal是女孩名字中的(等级)

我到目前为止的代码如下:我似乎无法弄明白。谢谢你的帮助。

#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 个答案:

答案 0 :(得分:3)

在您完成扫描列表之前,您承认失败(“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";
}

答案 1 :(得分:2)

在发布问题之前,您绝对可以对问题进行更多分析和隔离。

例如,您正在循环调用getline,该line1会从input中读取一行文本到line1。但是你对cout << "rank = " << rank << " boy_name = " << boy_name << " girl_name = " << girl_name << endl; 什么都不做。您可以使用iostream运算符读取其后的行上的数据字段。所以这将有效地跳过其他所有行。如果您只是在循环中进行调试完整性检查,就很容易判断:

{{1}}

然后你可以将你的问题表述为“我为什么只得到其他每一行”。这对人们来说更容易回答,但你也可能有机会自己回答。

另一个潜在的问题是,如果您使用.RTF“Rich Text”文件而不是普通文本文件。它可能有额外的垃圾,这会让你的代码感到困惑。家庭作业通常不会给你古怪的格式来处理,因为这是一个全新的蠕虫。

答案 2 :(得分:1)

首先,看起来你正试图打开一个富文本格式文件(.rtf)。这不起作用,因为该文件不仅包含文本,还包含其他数据(http://en.wikipedia.org/wiki/Rich_Text_Format)。

然后在您的代码中:while(getline(input,line1))每次迭代都会读取一行。这很好,但在循环内你做input >> rank >> boy_name >> girl_name;继续在下一行读取

您希望使用line1。您可以从line1构造一个stringstream,然后从中读取名称:

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

这和Beta在他的回答中所写的内容;你在名字不匹配的每一行“放弃”。