将输入文件存储到多种数据类型中

时间:2018-03-20 00:29:09

标签: c++ visual-c++

我坚持如何获取存储在包含空格字符的字符串中的名称,然后将其余的输入分别存储为int,char和double。换句话说,四种不同的数据类型:string,int,char,double。

这是我需要逐行读取和提取数据的文件内容。我需要名称提取适用于所有类型的名称。

此外,以下文件内容分别按此顺序:

字符串:名称
Int:帐号
字符:帐户类型
双倍:使用金额

John H. Doe 1001 H 5693.3

James Randolph,Jr。3333 H 1000.0

Sara Lawrence-Smith 2456 H 3999999.5

Good Time Industries 4678 C 10000000.1

Big Business,Inc。6757 I 12500849.9

Mom and Pop Shop 5002 C 4000000.7

O' Leary Company 8022 I 9999999.9

到目前为止,这是我的一些代码:

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

using namespace std;

void readBillingRecord(ifstream& fin, string& name, int& accNum, char& type, double& usage);

int main()
{
string billingDataFile = "Water Bill Records.txt";
string billingReportFile = "Water Bill Report.txt";
ifstream fin;
ofstream fout;
string name;
int accNum;
char type; 
double usage;

fin.open(billingDataFile);
if (fin.fail())
{
cout << "\nError opening " << billingDataFile << " file for reading. \nProgram Terminated. \n";
system("pause");
return EXIT_FAILURE;
}
readBillingRecord(fin, name, accNum, type, usage);
system("pause");
return 0;
}

void readBillingRecord(ifstream& fin, string& name, int& accNum, char& type, double& usage)
{
fin >> name >> accNum >> type >> usage;
cout << name << accNum << type << usage << endl;
}

2 个答案:

答案 0 :(得分:1)

我讨厌成为“那个家伙”,但是,这真的是在呼喊

  1. 正则表达式(尽管从字符串末尾开始计数的任何方法都可以)
  2. 不使用C ++(抱歉,我说这是该语言的忠实粉丝)
  3. 然而,如果失败了,并且假设没有任何尾随字段丢失(或“空”),那么提取这些字符串值的下一个最佳选择是(遗憾地):

    对于文件中的每一行:

    1. 向后扫描分隔符(空格),三次,注意不要越过行的开头;然后使用行的开头和那个偏移量(好吧,一个迭代器,希望)来构造一个新的字符串值
    2. 以您选择的方式提取剩余的三个值
    3. 要有效地执行此操作,您可能需要查看mmap()string_view

答案 1 :(得分:0)

使用流函数解析名称很困难。这是一个regex解决方案:

void readBillingRecord(ifstream& fin, string& name, int& accNum, char& type, double& usage)
{
    std::string line;
    std::regex r{R"(([\D]*) (\d*) (\w) (\d*.?\d*))"};
    std::smatch m;
    while(getline(fin, line)){
        std::regex_match(line, m, r);

        name = m[1];
        accNum = std::stoi(m[2]);
        type = std::string{m[3]}[0];
        usage = std::stod(m[4]);

        std::cout << name << accNum << type << usage << endl;
    }
}

进行更多错误检查:

void readBillingRecord(ifstream& fin, string& name, int& accNum, char& type, double& usage)
{
    std::string line;
    std::regex r{R"(([\D]*) (\d*) (\w) (\d*.?\d*))"};
    std::smatch m;
    while(getline(fin, line)){
        static int line_count{-1};
        ++line_count;
        if(!std::regex_match(line, m, r)) {
            std::cout << "No match for line " << line_count << " with text: " << line << '\n';
            continue;
        }
        name = m[1];
        accNum = std::stoi(m[2]);
        type = std::string{m[3]}[0];
        usage = std::stod(m[4]);

        std::cout << name << accNum << type << usage << endl;
    }
}

对于以下输入:

John H. Doe 1001 H 5693.3

James Randolph, Jr. 3333 H 1000.0
Sara Law3rence-Smith 2456 H 3999999.5
Good Time Industries 4678 C 10000000.1
Big Business, Inc. 6757 I 12500849.9
Mom and Pop Shop 5002 C 4000000.7
The O'Leary Company 8022 I 9999999.9

产地:

John H. Doe 1001H5693.3
No match for line 1 with text:
James Randolph, Jr. 3333H1000
No match for line 3 with text: Sara Law3rence-Smith 2456 H 3999999.5
Good Time Industries 4678C1e+07
Big Business, Inc. 6757I1.25008e+07
Mom and Pop Shop 5002C4e+06
The O'Leary Company 8022I1e+07