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

Posted

技术标签:

【中文标题】C ++匹配文件中的字符串并获取行号【英文标题】:C++ match string in file and get line number 【发布时间】:2011-12-08 10:21:40 【问题描述】:

我有一个包含前 1000 个婴儿名字的文件。我想向用户询问姓名...搜索文件...并告诉用户该名称对于男孩名字的排名以及对于女孩名字的排名。如果它不在男孩名或女孩名中,它会告诉用户它不在该性别的流行名字中。

文件的布局如下:

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

输入Michael 的期望输出为:

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

【问题讨论】:

这段代码不起作用吗?它是如何失败的?它有什么作用?你有什么问题? 它总是输出: 不在流行的男孩名字中。然后在下一行说 不在流行的女孩名字中。 嗯,是你在文件中输入的名字吗?如果不是,那么输出就是我对您的代码的期望... 与您的问题无关,但在 C++ 中,您通常在使用变量之前声明变量,而不是全部在函数的顶部。 你只是循环遍历文件中的所有行,有什么问题? 【参考方案1】:

在您完成扫描列表之前,您正在认输(“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】:

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

例如,您在一个调用getline 的循环中,它会从您的input 中将一行文本读入line1。但是你对line1 什么都不做。您使用 iostream 操作符来读取它之后的行中的数据字段。因此,这将有效地跳过所有其他行。很容易看出,如果您只是在循环中进行调试完整性检查,例如:

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

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

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

【讨论】:

感谢您的帮助。但是您不必说我需要在发布问题之前进行更多分析等。我已经在 Google 中搜索了 3 个小时的结果,而且我可能不太擅长理解 C++ 中的所有内容在上下文中的作用/含义。 不客气。但是你必须相信我,在 ***(以及一般的编程帮助社区)上,人们希望你指出一个更准确的点,你的理解从“好的,我明白这个”到“但是,我不明白”明白”。这比粘贴代码并说“它没有做我想做的事”要好得多,而不解释它做了什么 ......以及你尝试过什么样的事情作为回应。另见:mattgemmell.com/2008/12/08/what-have-you-tried【参考方案3】:

首先,您似乎正在尝试打开富文本格式文件 (.rtf)。这不起作用,因为该文件不仅包含文本,还包含其他数据 (http://en.wikipedia.org/wiki/Rich_Text_Format)。

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

您想使用line1。您可以从 line1 构造一个字符串流,然后从中读取名称:

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

那以及 Beta 在他的回答中所写的内容;您在名称不匹配的每一行中“放弃”。

【讨论】:

以上是关于C ++匹配文件中的字符串并获取行号的主要内容,如果未能解决你的问题,请参考以下文章

C# - RegEx - 获取两行之间的字符串

查找文件中所有出现的字符串并在 Perl 中打印其行号

linux-grep

使用 grep 时获取行号

如果前缀是非常大的文件中的某个字符串,则在括号之间获取/匹配文本[关闭]

匹配 csv 文件中的文本,用于 X 首行和最后 X 个结果,并在 lua 中获取值