简体   繁体   English

从文本文件中读取整数和字符串并存储在并行数组中

[英]Reading integers and strings from a text file and storing in parallel arrays

I have a text file that stores the index, student name and student ID and I am trying to read them into an array of integers index , arrays of strings studentName and studentID .我有一个存储索引、学生姓名和学生 ID 的文本文件,我正在尝试将它们读入整数数组index 、字符串数组studentNamestudentID I'm having problems storing the student's names because they could be more than a single word.我在存储学生姓名时遇到问题,因为它们可能不止一个单词。 I could separate the items in the text file by commas and use getline but that would mean the index array will have to be a string type.我可以用逗号分隔文本文件中的项目并使用getline但这意味着index数组必须是字符串类型。 Is there a workaround for this without changing the original text file?在不更改原始文本文件的情况下是否有解决方法?

Original file:原始文件:

1 James Smith E2831
2 Mohammad bin Rahman M3814
3 MJ J4790

const int SIZE = 3;
int index[SIZE];
string studentName[SIZE], studentID[SIZE];
fstream infile("students.txt");

if(infile.is_open()){
    int i = 0;
    while(i < 3){
        infile >> index[i] >> studentName[i] >> studentID[i];
        i++;
    }
}

Changed file:更改的文件:

1,James Smith,E2831
2,Mohammad bin Rahman,M3814
3,MJ,J4790
const int SIZE = 3;
string index[SIZE];
string studentName[SIZE], studentID[SIZE];
fstream infile("students.txt");

if(infile.is_open()){
    int i = 0;
    while(i < 3){
        getline(infile, index[i],',');     //index array is string
        getline(infile, studentName[i],',');
        getline(infile, studentID[i],'\n');
        i++;
    }
}

There are so many possible solutions that it is hard to tell, what should be used.有很多可能的解决方案,很难说应该使用什么。 Depends a little bit on your personal style and how good you know the language.取决于您的个人风格以及您对语言的了解程度。

In nearly all solutions you would (for safety reasons) read a complete line with std::getline then put either split the line manually or use a std::istringstream for further extraction.在几乎所有解决方案中,您都会(出于安全原因)使用std::getline读取完整的行,然后手动拆分该行或使用std::istringstream进行进一步提取。

A csv input would be preferred, because it is more clear what belongs together.最好使用 csv 输入,因为它更清楚什么属于一起。

So, what are the main possibilities?那么,主要的可能性是什么? First the space separated names首先是空格分隔的名称

  • You could use a std::regex and then search or match for example "(\d) ([\w ]+) (\w+)"您可以使用std::regex然后搜索或匹配例如 "(\d) ([\w ]+) (\w+)"
  • You cou create substrings, by searching the first space from the right side of the string, which would be the "studentID", then the getting the rest is simple您可以通过搜索字符串右侧的第一个空格(即“studentID”)来创建子字符串,然后获取其余部分很简单
  • You could use a while loop and read all parts of the string and put it in a std::vector .您可以使用 while 循环并读取字符串的所有部分并将其放入std::vector中。 The first element in the std::vector is then the index, the last the ID and the rest would be the name. std::vector中的第一个元素是索引,最后一个是 ID,其余的是名称。
  • You could parse the string with formatted input functions.您可以使用格式化的输入函数解析字符串。 First read the index as number, then the rest as stringm the split of the last part and get the id.首先将索引读取为数字,然后将其余部分读取为最后一部分的拆分并获取 id。

And many more还有很多

For csv, you could use对于 csv,您可以使用

  • the std::sregex_token_iterator looking for the comma as separator寻找逗号作为分隔符的std::sregex_token_iterator
  • Use also a std::vector and later pick the needed values.也使用std::vector并稍后选择所需的值。
  • Use a mixture of formatted and unformatted input混合使用格式化和未格式化的输入

Example:例子:

std::getline(std::getline(infile >> index >> Comma >> std::ws, name, ','), id);

It is up to you, what you would like to implement.这取决于你,你想实现什么。

Write your preference in the comment, then I will add some code.在评论中写下你的偏好,然后我会添加一些代码。

It's an error to read one line into one student property with the given input format.使用给定的输入格式将一行读入一个学生属性是错误的。 You need to read one line and then split the information in this line into the 3 properties.您需要阅读一行,然后将这一行中的信息拆分为 3 个属性。

std::stoi can be used to convert to convert the first part of the line read to an int . std::stoi可用于 convert 将读取的行的第一部分转换为int Futhermore it's simpler to handle the data, if you create a custom type storing all 3 properties of a student instead of storing the information in 3 arrays.此外,如果您创建一个自定义类型来存储学生的所有 3 个属性,而不是将信息存储在 3 个数组中,那么处理数据会更简单。

Note that the following code requires the addition of logic to skip whitespace directly after (or perhaps even before) the ',' chars.请注意,以下代码需要添加逻辑以直接在','字符之后(甚至可能之前)跳过空格。 Currently it simply includes the whitespace in the name/id.目前它只是在名称/ID 中包含空格。 I'll leave that task to you.我会把这个任务留给你。

struct Student
{
    int m_index;
    std::string m_name;
    std::string m_id;
};

std::vector<Student> readStudents(std::istream& input)
{
    std::vector<Student> result;

    std::string line;
    while (std::getline(input, line))
    {
        size_t endIndex = 0;
        auto index = std::stoi(line, &endIndex);
        if (line[endIndex] != ',')
        {
            throw std::runtime_error("invalid input formatting");
        }
        ++endIndex;
        auto endName = line.find(',', endIndex);
        if (endName == std::string::npos)
        {
            throw std::runtime_error("invalid input formatting");
        }
        result.push_back(Student{ index, line.substr(endIndex, endName - endIndex), line.substr(endName + 1) });
    }

    return result;
}

int main() {
    std::istringstream ss(
        "1,James Smith,E2831\n"
        "2, Mohammad bin Rahman, M3814\n"
        "3, MJ, J4790\n");

    auto students = readStudents(ss);

    for (auto& student : students)
    {
        std::cout << "Index=" << student.m_index << "; Name=" << student.m_name << ";Id=" << student.m_id << '\n';
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM