我正在尝试从学生的文本文件中读取内容,并将每一行分配给struct数据成员。
文本文件结构如下:
Name,Student code, Ability,Consistency,Program name:Subject list
文件中有两名学生:
Average Ant,204932,50,5,Short course:1
Brilliant Bison,234543,80,3,Bachelor of Bounciness:2,5,3
除了最后一部分(主题列表),学生之间的长度不同,我可以毫无问题地阅读所有信息。 我该如何编写代码,以便如果一个学生只有1个像平均蚂蚁这样的科目,我可以将其推入subjectList向量,但如果他们有3个像出色的野牛一样,我仍然可以毫无问题地将它们全部推入。
我的代码:
struct Student
{
string name;
int code;
int ability;
int consistency;
string programName;
vector<int> subjectList;
};
void createStudents(string fileName)
{
string tempSubjectId;
int subjectId;
//temp variable to then use to convert them to int.
string codeTemp, abilityTemp, consistencyTemp;
std::ifstream studentFile(fileName);
//A new student data member is created
Student newStudent;
if(studentFile.is_open() && studentFile.good())
{
cout << " " << endl;
cout << "---Reading from Students---" << endl;
while(getline(studentFile,newStudent.name, ','))
{
//we go get each value which is delimited by a comma and one by a colon
//getline(studentFile, newStudent.name, ',');
//To convert the strings to an int, the string is given to a temporary variable
//Then the temporary variable is parsed to an int using stoi and the code datamember from the struct is assign to that new int
getline(studentFile, codeTemp, ',');
newStudent.code = stoi(codeTemp);
getline(studentFile, abilityTemp, ',');
newStudent.ability = stoi(abilityTemp);
getline(studentFile, consistencyTemp, ',');
newStudent.consistency = stoi(consistencyTemp);
getline(studentFile, newStudent.programName, ':');
//want to push ints into subject list here.
//The new struct data member is added to the vector and returned for further use.
studentList.push_back(newStudent);
}
//file is then closed
studentFile.close();```
答案 0 :(得分:3)
在主循环中,将整行读入std::string
,然后使用std::istringstream
解析每一行,并使用内部循环读取主题int,例如:
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
struct Student
{
std::string name;
int code;
int ability;
int consistency;
std::string programName;
std::vector<int> subjectList;
};
std::vector<Student> studentList;
void createStudents(std::string fileName)
{
std::string tempLine;
//temp variable to then use to convert them to int.
std::string tempStr;
std::ifstream studentFile(fileName);
if (studentFile.is_open())
{
std::cout << " " << std::endl;
std::cout << "---Reading from Students---" << std::endl;
while (std::getline(studentFile, tempLine))
{
std::istringstream iss(tempLine);
//A new student data member is created
Student newStudent;
//we go get each value which is delimited by a comma and one by a colon
std::getline(iss, newStudent.name, ',');
//To convert the strings to an int, the string is given to a temporary variable
//Then the temporary variable is parsed to an int using stoi and the code datamember from the struct is assign to that new int
std::getline(iss, tempStr, ',');
newStudent.code = std::stoi(tempStr);
std::getline(iss, tempStr, ',');
newStudent.ability = std::stoi(tempStr);
std::getline(iss, tempStr, ',');
newStudent.consistency = std::stoi(tempStr);
std::getline(iss, newStudent.programName, ':');
// push ints into subject list
while (std::getline(iss, tempStr, ',')) {
newStudent.subjectList.push_back(std::stoi(tempStr));
}
//The new struct data member is added to the vector and returned for further use.
studentList.push_back(std::move(newStudent));
}
//file is then closed
studentFile.close();
}
}
答案 1 :(得分:0)
您需要另一个循环,并像这样读取字符串流
#include <sstream>
string subjectList;
getline(studentFile, subjectList); // read all the subjects
istringstream iss(subjectList); // put into a string stream for parsing
string subject;
while (getline(iss, subject, ',')) // read from string stream, spliting on commas
{
newStudent.subjectList.push_back(stoi(subject)); // add to subject list
}
未经测试的代码。
答案 2 :(得分:0)
这里是您可以尝试的修改后的代码,[未测试]
struct Student
{
string name;
int code;
int ability;
int consistency;
string programName;
vector<int> subjectList;
};
void createStudents(string fileName)
{
string tempSubjectId;
int subjectId;
//temp variable to then use to convert them to int.
string codeTemp, abilityTemp, consistencyTemp;
std::ifstream studentFile(fileName);
//A new student data member is created
Student newStudent;
if(studentFile.is_open() && studentFile.good())
{
cout << " " << endl;
cout << "---Reading from Students---" << endl;
while(getline(studentFile,newStudent.name, ','))
{
//we go get each value which is delimited by a comma and one by a colon
//getline(studentFile, newStudent.name, ',');
//To convert the strings to an int, the string is given to a temporary variable
//Then the temporary variable is parsed to an int using stoi and the code datamember from the struct is assign to that new int
getline(studentFile, codeTemp, ',');
newStudent.code = stoi(codeTemp);
getline(studentFile, abilityTemp, ',');
newStudent.ability = stoi(abilityTemp);
getline(studentFile, consistencyTemp, ',');
newStudent.consistency = stoi(consistencyTemp);
getline(studentFile, newStudent.programName, ':')
std::string line;
std::vector <int> arr;
getline(studentFile, line);
boost::split(arr, line, [](char c) {return (c==',');})
newStudent.subjectList = arr;
}
//file is then closed
studentFile.close();```
答案 3 :(得分:0)
我大力支持Arash Partow的String Toolkit Library。实际上,它几乎可以神奇地处理阅读和解析文本。您可以设置一个lamba来逐行解析,并根据您的结构进行大量其他工作。这是一个简单的例子。
#include <iostream>
#include <vector>
#include <string>
#include <strtk.hpp> // String Toolkit Library
struct Student_t
{
string name;
int code;
int ability;
int consistency;
string programName;
vector<int> subjectList;
};
const char *whitespace = " \t\r\n\f";
// in case you wanted to parse on stuff with comma or whitespace
// it is just a matter of choosing what you want to parse
// by
/// const char *whitespace_and_punctuation = " \t\r\n\f;,=";
const char *comma_and_colon = ",:";
int main()
{
std::fstream input("file.txt", std::ios::in );
std::string line;
std::vector<Student_t> students;
while(getline(input_strm, line) )
{
// clean up the string (precaution)
strtk::remove_leading_and_trailing(whitespace, line);
Student_t s; // declare an instance
// The parse function will fill in & convert the values into the variables
// Since the last element is a vector, all the remaining integers will
// be converted.
// the example does assume that a colon is used only once
if(!strtk::parse( line, comma_and_colon, s.name, s.code,
s.ability, s.consistency, s.programName, s.subjectList ) ) {
continue;
// you may want to handle the parse error differently
}
students.push_back(s);
}
}
我已经使用String Toolkit库回答了许多问题,其他人也回答了。 该库是C ++,仅标头且快速。图书馆有很多例子,很好的文档。