搜索2D数组并返回整行

时间:2016-02-09 23:24:36

标签: c++ arrays file-io

我是C ++的新手,我很难弄清楚2D数组是如何工作的。

我正在创建一个程序,它将.txt文件填入“驱动程序许可证记录”并读入它们,然后让用户在“数据库”中搜索姓氏,年龄,或者是否司机已登记投票(y / n)。

示例.txt文件如下所示:

4
Chris Jones 19 Y 374122
Pat Smith 23 N 863901
Kyle Howard 31 Y 673911
Samantha Pratter 27 Y 874309

我的主要方法是

int main(int argc, char* argv[])
{
Executive exec(argv[1]);
exec.run();
return (0);
}

以下是我的Executive课程的代码:

#include <iostream>
#include <fstream>
#include "Executive.h"
#include "DriversLicenseRecord.h"
using namespace std;

Executive::Executive(char* filename){

    int n;
    ifstream inp(filename);

    inp >> n;
    num_records=n;

    DriversLicenseRecord** record = new DriversLicenseRecord*[n];
    for(int i=0; i<n; i++){
        record[i] = new DriversLicenseRecord(inp);
    }

}
//here is where I am pretty much guessing
void Executive::run(){
    int x=0;
    do{
        cout << "1: Query last name" << endl << "2: Query age range" << endl << "3: Query registered voters" << endl << "4: Quit" << endl;
        cin >> x;
        if(x==1){
            string name;
            cout << "Enter last name: ";
            cin >> name;
            /**for(int i=0; i<num_records; i++){
                if(name==record[i]){
                    cout << record[i];
                }
            }*/
        }
        else if(x==2){
            int max;
            int min;
            cout << "Enter age range: " << endl << "min: ";
            cin >> min;
            cout << "max: ";
            cin >> max;

        }
        else if(x==3){
        }
    }while(x!=4);
}

这是我的DriversLicenseRecord课程:

#include "DriversLicenseRecord.h"
using namespace std;

DriversLicenseRecord::DriversLicenseRecord(ifstream& inp){
    inp >> first_name;
    inp >> last_name;
    inp >> age;
    inp >> vote;
    inp >> license;
}

首先,我想知道我是否正确读取了值,我的理解是它跳过了在空白处读取,因此DriversLicenseRecord应该得到正确的值。

其次我不知道如何搜索这个,并返回整行。

以下是给定.txt文件的输出示例:

1. Query last name
2. Query age range
3. Query registered voters
4. Quit

3 // user input

Chris Jones 19 Y 374122

Kyle Howard 31 Y 673911

Samantha Pratter 27 Y 874309

只需向正确的方向进行一次小推动就会非常有帮助,我整个星期都在努力解决这个问题并且没有取得多大进展。

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以避免使用2D阵列。
方法1
请改用vector<string>。使事情更容易处理。 从文本文件中读取并将每一行作为字符串存储在向量中。

然后,当您搜索特定的查询字符串时,您需要做的就是处理向量中的每个字符串。

因此,要从输入文本文件中读取,您可以执行以下操作:

ifstream inpFile(myfile.txt);
string line;
vector<string> myInpFile;
while(getline(inpFile,line))
{     
 myInpFile.push_back(line);
}

我将把字符串搜索的实现留作练习。看看如何处理字符串here

方法2
或者,您可以直接从文件中读取您需要的内容,然后搜索字符串。内存中根本不需要DriversLicenseRecord。但这不是你的TA似乎在寻找的东西。

答案 1 :(得分:0)

您的代码中存在一些错误,但我首先要说的是(1)这里不需要2D数组,(2)您不能创建2D数组Executive::Executive()。对于(1):在此任务中您需要的只是DriversLicenseRecord个对象的一维数组(或容器)。然后,您可以查询单个对象的字段,并将它们的值与查询进行比较,以搜索特定记录。对于(2),你创建的只是一个指向DriversLicenseRecord个对象的一维数组。

这是出现错误的地方。

首先,变量records是构造函数的本地变量。一旦c&tor; tor返回,records将被销毁。您无法在构造函数外部访问它。此外,您分配的内存将丢失,从而造成内存泄漏。

其次,虽然创建数组是正确的,但迭代不是。以下是如何迭代数组并查询字段的方法:

for(int i=0; i < num_records; i++){
   // note the -> : because we're using a pointer, not the object itself
   if(name == m_records[i]->first_name){
       cout << m_records[i]->first_name;
       // or, if you define operator<<(istream&, const DriversLicenseRecord&):
        cout << *(m_records[i]);
   }

最后,为什么你必须使用动态数组。事实是,在您阅读文件之前,您不知道条目的数量,并且您不能创建除new以外的可变长度数组,除非在函数内部作为局部变量,但后来看到#1:它在功能退出时丢失了。但是,您可以创建一个动态的记录数组,而不是指向记录的指针。为此,您需要为DriversLicenseRecord提供默认构造函数,然后只需从文件中即时填写字段。 (不是您与DriversLicenseRecord::DriversLIcenseRecord(istream&)一起使用的语法,而不是默认的c&#39;)

接下来,我将使用STL容器和算法来解决这个问题。

1。切换到std::vector,这样可以更安全,更方便使用。

2。我真的不喜欢使用D.L.R.参数创建istream类的想法。如果你想使用流,你可以做的是定义istream& operator>>(istream&, DriverLicenseRecord&),然后像这样使用漂亮的STL语法:

std::istream& operator>>(std::istream& str, DriversLicenseRecord& rec)
{
    std::string str;
    str >> rec.first_name >> rec.last_name >> rec.age >> temp >> rec.license;
    rec.can_vote = (temp == "Y");
    return str;
}

然后是一些STL美女:

class Executive {
    typedef std::istream_iterator<DriversLicenseRecord> in_driver_it;
    std::vector<DriversLicenseRecord> records;
public:
    Executive(const std::string& file)
    {
        std::ifstream inp(file);
        int n; inp >> n;
        std::copy(in_driver_it(inp), in_driver_it(), std::back_inserter(records));
    }
};

输出相同。

长话短说:here is the complete sample code using the standard library,另一方面,这不是最短但很简单。耗尽空间!