如何在C ++中读取带有逗号分隔值的流?

穆罕默德

我想强调以下一个基本问题:

假设您有一个CSV文件,并用输入标题填充了单元格

代码应从.csv文件读取此内容并将结果写入.csv文件。还可以对输出的案例总数和案例的平均值进行编码。这是SO的样本,我想看看如何有效地采用它来完成此基本示例。

   void create() 
{ 
    // file pointer 
    fstream fout; 

    // opens an existing csv file or creates a new file. 
    fout.open("reportcard.csv", ios::out | ios::app); 

    cout << "Enter the details of 5 students:"
        << " roll name maths phy chem bio"; 
    << endl; 

    int i, roll, phy, chem, math, bio; 
    string name; 

    // Read the input 
    for (i = 0; i < 5; i++) { 

        cin >> roll 
            >> name 
            >> math 
            >> phy 
            >> chem 
            >> bio; 

        // Insert the data to file 
        fout << roll << ", "
            << name << ", "
            << math << ", "
            << phy << ", "
            << chem << ", "
            << bio 
            << "\n"; 
    } 
} 

另外,阅读特定记录

void read_record() 
{ 

    // File pointer 
    fstream fin; 

    // Open an existing file 
    fin.open("reportcard.csv", ios::in); 

    // Get the roll number 
    // of which the data is required 
    int rollnum, roll2, count = 0; 
    cout << "Enter the roll number "
        << "of the student to display details: "; 
    cin >> rollnum; 

    // Read the Data from the file 
    // as String Vector 
    vector<string> row; 
    string line, word, temp; 

    while (fin >> temp) { 

        row.clear(); 

        // read an entire row and 
        // store it in a string variable 'line' 
        getline(fin, line); 

        // used for breaking words 
        stringstream s(line); 

        // read every column data of a row and 
        // store it in a string variable, 'word' 
        while (getline(s, word, ', ')) { 

            // add all the column data 
            // of a row to a vector 
            row.push_back(word); 
        } 

        // convert string to integer for comparision 
        roll2 = stoi(row[0]); 

        // Compare the roll number 
        if (roll2 == rollnum) { 

            // Print the found data 
            count = 1; 
            cout << "Details of Roll " << row[0] << " : \n"; 
            cout << "Name: " << row[1] << "\n"; 
            cout << "Maths: " << row[2] << "\n"; 
            cout << "Physics: " << row[3] << "\n"; 
            cout << "Chemistry: " << row[4] << "\n"; 
            cout << "Biology: " << row[5] << "\n"; 
            break; 
        } 
    } 
    if (count == 0) 
        cout << "Record not found\n"; 
} 


  [1]: https://i.stack.imgur.com/q6VfZ.png
泰德·林格莫

我主要集中在增加重载operator<<operator>>因为你表现出这些早期的一些兴趣和描述他们在代码中的注释在做什么。

由于您要混合使用逗号分隔的流和其他流的输入和输出,因此我添加了用于CSV流传输的适配器以及用于向/从用户流传输的重载。

首先,创建一个class,将所有在一起的数据保留在一个数据记录中。我在struct这里做了一个简单的介绍,它默认情况下class可以public访问其成员。

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

// your student record
struct student {
    std::string name; // It's usually good to have larger types first so name goes first
    int roll;
    int math;
    int phy;
    int chem;
    int bio;
};

// read a student from an istream (like std::cin) - whitespace separated
std::istream& operator>>(std::istream& is, student& s) {
    return is >> s.roll >> s.name >> s.math >> s.phy >> s.chem >> s.bio;
}

// write a student to an ostream (like std::cout)
std::ostream& operator<<(std::ostream& os, const student& s) {
    return os << "Details of Roll " << s.roll << ":\n"
              << "Name: " << s.name << '\n'
              << "Maths: " << s.math << '\n'
              << "Physics: " << s.phy << '\n'
              << "Chemistry: " << s.chem << '\n'
              << "Biology: " << s.bio << '\n';
}
//--------------------------------------------------------------------------------------
// An adapter for comma separated streaming
struct CSVStudent {
    CSVStudent(student& s) : stud(s) {}
    CSVStudent(const CSVStudent&) = delete;

    // The CSVStudent holds a reference to a "student"
    student& stud;
};

// read a record from an istream - comma separated
std::istream& operator>>(std::istream& is, CSVStudent& csvstud) {
    std::string line;

    student& s = csvstud.stud; // an alias to the student to have to type less

    if(std::getline(is, line)) { // read a complete line
        // put the line in an istringstream for extraction:
        std::istringstream ss(line);

        char delim; // a dummy for reading commas

        // Extract the comma separated values. "delim" is not checked so it could be
        // any char breaking up the int:s.
        //
        // The below does things in the following order:
        // 1.  "ss >> s.roll >> delim"
        //     This extracts roll and a comma and returns
        //     a reference to ss, which is used in 2.
        // 2.  std::getline(ss, s.name, ',')
        //     Extracts a string until a comma is encountered.
        // 3.  Normal extraction for the rest of the int:s with the
        //     dummy variable "delim" where the commas are supposed to be.

        if(not(std::getline(ss >> s.roll >> delim, s.name, ',') >> s.math >> delim >>
               s.phy >> delim >> s.chem >> delim >> s.bio)) {
            // If we get here, the extraction from the istringstream failed, so set
            // the failstate on the istream too. Note the "not" on the line above.
            is.setstate(std::ios::failbit);
        }
    }
    return is;
}

// write a record to an ostream - comma separated
std::ostream& operator<<(std::ostream& os, const CSVStudent& csvstud) {
    const student& s = csvstud.stud;
    os << s.roll << ',' << s.name << ',' << s.math << ',' << s.phy << ',' << s.chem
       << ',' << s.bio << '\n';
    return os;
}
//--------------------------------------------------------------------------------------
// get all students in the file as a std::vector<student>
std::vector<student> read_student_file(const std::string& filename) {
    std::vector<student> retval;
    std::ifstream fin(filename);
    if(fin) { // file opened successfully
        student stud;
        CSVStudent csvstud{stud}; // holds a reference to stud

        // loop for as long as student records can be read successfully
        while(fin >> csvstud)       // use the csv sdapter
            retval.push_back(stud); // and put the stud in the vector
    }
    return retval;
}
//--------------------------------------------------------------------------------------
void create(const std::string& filename) {
    // open an existing csv file or creates a new file.
    std::ofstream fout(filename, std::ios::out | std::ios::app);
    if(fout) {
        std::cout << "Enter the details of 5 students:"
                     " roll name maths phy chem bio\n";

        // Read the input
        for(int i = 0; i < 5; i++) {
            student stud;
            std::cout << (i + 1) << ": ";
            if(std::cin >> stud) {
                // Insert the data to file if one was entered successfully
                fout << CSVStudent(stud); // uses the adapters operator<<
            } else {
                std::cerr << "You failed to enter data for student " << (i + 1) << '\n';
                break;
            }
        }
    }
}
//--------------------------------------------------------------------------------------
int main() {
    std::string filename = "reportcard.csv";

    std::vector<student> students = read_student_file(filename);

    std::cout << "There are " << students.size() << " students in the file.\n";
    if(not students.empty()) {
        // show the last record if there are any records in the file
        std::cout << "Record " << students.size() << " is:\n\n";
        std::cout << students.back() << '\n';
    }

    // create 5 new records
    create(filename);
}

如果reportcard.csv包含以下内容:

1,Ted,1,2,3,4
2,Foo,2,3,4,5
3,Bar,3,4,5,6
4,Baz,4,5,6,7
5,Bork,5,6,7,8

该程序应如下启动:

There are 5 students in the file.
Record 5 is:

Details of Roll 5:
Name: Bork
Maths: 5
Physics: 6
Chemistry: 7
Biology: 8

Enter the details of 5 students: roll name maths phy chem bio
1: <and here is where you're supposed to enter the first of 5 new students>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在C ++中从文本文件中读取带有逗号的逗号分隔值

如何在 R 中读取带有管道的逗号分隔字段作为文本分隔符

如何在熊猫中读取带有空格分隔值的文件

如何在XSLT中添加所有逗号分隔的值

如何使用javascript读取xml中的逗号分隔值

如何在C中读取以空格分隔的值?

如何使用 SQL 查询查看带有 group by 子句的逗号分隔字符串中的列值?

如何在带有逗号分隔符的python中输入数字?

我的数据在列的值中有逗号,这也是一个分隔符,如何在 python 中通过 csv.reader 读取它

如何读取由“ ”分隔但带有逗号的十进制数的数据

如何在熊猫中读取带有引号和逗号的CSV文件?

C#读取CSV文件| 具有标题行和逗号分隔的值

如何在c#中的datagridview列中添加用逗号分隔的值

如何在C#中的表中存储逗号分隔的值

如何为带有逗号分隔值的字段设置“ where”子句?

如何在表单中显示逗号分隔值

如何在bash中对逗号分隔的值进行排序?

如何在单列中显示多个用逗号分隔的值?

如何在mysql中匹配逗号分隔的值并获取值

如何在PostgreSQL中逐行存储逗号分隔的值

如何在Notepad ++中垂直对齐逗号分隔的值?

如何在变量中获取行并用逗号分隔值?

Jmeter,如何在jmeter中传递逗号分隔的多个值

如何在 SQL 中以逗号分隔的行存储列值

如何在 mvc 列表中显示逗号分隔值

如何在Excel中获取逗号分隔的值?

如何在 preg_match 中调用逗号分隔值

如何从流中读取空格分隔的单词?

如何在Python中读取带有分隔符的文件并在末尾附加字符?