Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 字符串和文件有问题_C++_File Io_Segmentation Fault - Fatal编程技术网

C++ 字符串和文件有问题

C++ 字符串和文件有问题,c++,file-io,segmentation-fault,C++,File Io,Segmentation Fault,我正在为我的CS课程做一个实验,包括打开三个文件并根据获得的数据向第四个文件提供输出。我遇到了一些问题(我对C++有些生疏),代码让我头疼。我遇到过字符串错误和分段错误 #include <iostream> #include <iomanip> #include <fstream> #include <list> #include <vector> #include <algorithm> using namespace

我正在为我的CS课程做一个实验,包括打开三个文件并根据获得的数据向第四个文件提供输出。我遇到了一些问题(我对C++有些生疏),代码让我头疼。我遇到过字符串错误和分段错误

#include <iostream>
#include <iomanip>
#include <fstream>
#include <list>
#include <vector>
#include <algorithm>

using namespace std;

//Necessary objects/structures
struct student {                            //create a structure to contain all data     consistent to the student
    string ID, name, address, phone;
    bool is_In_Query;
    list<string> class_Grade;               //Dynamic list to contain all letter grades since we don't know how many there will be
};

//Prototypes
bool readStudentFile(string, vector<student>);
bool readGradeFile(string, vector<student>);//returning a boolean will report if read was a success
bool readQueryFile(string, vector<student>);
void outputReportFile(string, vector<student>);
float calculateGPA(student);                //Pass all calculations and reading to functions to simplify and manage code
void reportFileError(int);                  //Reports a file error. "1" is Student, "2" is Grade, "3" is Query
int isSame(string, vector<student>);

int main(int argc, const char* argv[])
{
    vector<student> studentList;            //Allow a range in number of students


    if (!readStudentFile("students.txt", studentList)){
        if (!readGradeFile("grades.txt", studentList)){
            if(!readQueryFile("query.txt", studentList))
                outputReportFile("report.txt", studentList);
            else
                reportFileError(3);
        }
        else
            reportFileError(2);
    }
    else
        reportFileError(1);

    return 0;                               //Termination

/*
    if (!readStudentFile(argv[1], studentList)){
        if (!readGradeFile(argv[2], studentList)){
            if(!readQueryFile(argv[3], studentList))
                outputReportFile(argv[4], studentList);
            else
                reportFileError(3);
        }
        else
            reportFileError(2);
    }
    else
        reportFileError(1);

    return 0;                               //Termination
*/
}


bool readStudentFile(string fileToRead, vector<student> studentInfo)
{
    ifstream inFile;
    int index = 0;

    //inFile.open(fileToRead.c_str());            Original opening line
    inFile.open(fileToRead.c_str(), ifstream::in);

    if (!inFile.good())
        return false;
    else while (!inFile.eof()) {            //Read in order
        getline(inFile, studentInfo[index].ID);
        getline(inFile, studentInfo[index].name);
        getline(inFile, studentInfo[index].address);
        getline(inFile, studentInfo[index].phone);
        ++index;                            //We use a prefix to insure that index is incremented BEFORE the jump back to the else-while
    }
    inFile.close();
    return true;
}

bool readGradeFile(string fileToRead, vector<student> studentInfo)
{
    ifstream inFile;
    string temp;
    int sameID = 0;

    inFile.open(fileToRead.c_str(), ifstream::in);

    if (inFile.fail())
        return false;
    else while (!inFile.eof()) {            //Got more? Ok, let's go!
        cin.ignore();                       //The class ID is not necessary for our computation
        getline(inFile, temp);              //Obtain student ID
        sameID = isSame(temp, studentInfo); //Find it in our list of IDs
        if (sameID != -1){                  //If there is a match, get letter grade
            getline(inFile, temp);
            studentInfo[sameID].class_Grade.push_back(temp);
        }
                                            //No match? Ignored.
    }
    inFile.close();
    return true;
}

bool readQueryFile(string fileToRead, vector<student> studentInfo)
{
    ifstream inFile;
    int sameID = 0;
    string temp;

    inFile.open(fileToRead.c_str(), ifstream::in);

    if (inFile.fail())
        return false;
    else while (!inFile.eof()) {
        getline(inFile, temp);
        sameID = isSame(temp, studentInfo); //We get an ID, compare it
        if (sameID != -1)                   //If it's in there, we'll flag it to not report a GPA of 0 due to a bug
            studentInfo[sameID].is_In_Query = true;
    }
    inFile.close();
    return true;
}

void outputReportFile(string fileToWrite, vector<student> studentInfo)
{
    ofstream outFile;

    outFile.open(fileToWrite.c_str(), ifstream::out);
    outFile.setf(ios::fixed | ios::showpoint);

    for(int x = 0; x < studentInfo.size(); x++){
        if (studentInfo[x].is_In_Query){
            outFile << setw(12) << studentInfo[x].ID;
            outFile << fixed << setprecision(2) << setw(7) << calculateGPA(studentInfo[x]);
            outFile << studentInfo[x].name;

        }
    }

    cout << "Finished.\n";
}    

float calculateGPA(student scholar)
{
    float gpa = 0;
    if (scholar.class_Grade.size() == 0)
            return 0;
    else {
        for(list<string>::iterator it = scholar.class_Grade.begin(); it != scholar.class_Grade.end(); ++it)
        {
            if(*it == "A")
                gpa += 4.0;
            else if (*it == "A-")
                gpa += 3.7;
            else if (*it == "B+")
                gpa += 3.4;
            else if (*it == "B")
                gpa += 3.0;
           else if (*it == "B-")
                gpa += 2.7;
            else if (*it == "C+")
                gpa += 2.4;
            else if (*it == "C")
                gpa += 2;
            else if (*it == "C-")
                gpa += 1.7;
            else if (*it == "D+")
                gpa += 1.4;
            else if (*it == "D")
                gpa += 1.0;
            else if (*it == "D-")
                gpa += 0.7;
            else if (*it == "E")
               gpa += 0;
        }
    }
    gpa = gpa / scholar.class_Grade.size();
    return gpa;
}

int isSame(string id, vector<student> studentInfo)
{
    for (int x = 0; x < studentInfo.size(); x++)
    {
        if (id.compare(studentInfo[x].ID) == 0)
            return x;
    }

    return -1;
}

void reportFileError(int report_num)
{
    switch(report_num){
        case 1 :
            cout << "No valid student file" << endl;
            break;
        case 2 :
           cout << "No valid grade file" << endl;
            break;
        case 3 :
            cout << "No valid query file" << endl;
            break;
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//必要的物体/结构
struct student{//创建一个包含与学生一致的所有数据的结构
字符串ID、姓名、地址、电话;
布尔是查询中的布尔;
list class_Grade;//动态列表包含所有字母等级,因为我们不知道有多少字母等级
};
//原型
bool readStudentFile(字符串、向量);
bool readgrade文件(字符串、向量)//如果读取成功,则返回布尔值将报告
bool readQueryFile(字符串、向量);
无效输出报告文件(字符串、向量);
浮动计算器EGPA(学生)//将所有计算和读取传递给函数,以简化和管理代码
无效报告文件错误(int)//报告文件错误。“1”是学生,“2”是年级,“3”是查询
int-isname(字符串,向量);
int main(int argc,const char*argv[]
{
vector studentList;//允许学生数量的范围
如果(!readStudentFile(“students.txt”,studentList)){
如果(!readgrade文件(“grades.txt”,studentList)){
如果(!readQueryFile(“query.txt”,studentList))
输出报告文件(“report.txt”,studentList);
其他的
报告文件错误(3);
}
其他的
报告文件错误(2);
}
其他的
reportFileError(1);
返回0;//终止
/*
如果(!readStudentFile(argv[1],studentList)){
如果(!ReadGrade文件(argv[2],学生列表)){
if(!readQueryFile(argv[3],studentList))
输出报告文件(argv[4],学生列表);
其他的
报告文件错误(3);
}
其他的
报告文件错误(2);
}
其他的
reportFileError(1);
返回0;//终止
*/
}
bool readStudentFile(字符串文件toread,向量studentInfo)
{
河流充填;
int指数=0;
//infle.open(fileToRead.c_str());原始打开行
open(fileToRead.c_str(),ifstream::in);
如果(!infle.good())
返回false;
else while(!infle.eof()){//按顺序读取
getline(infle,studentInfo[index].ID);
getline(infle,studentInfo[index].name);
getline(infle,studentInfo[index].地址);
getline(infle,studentInfo[index].phone);
++index;//我们使用前缀确保在跳回else之前增加索引
}
infle.close();
返回true;
}
bool readgrade文件(字符串文件读取,向量studentInfo)
{
河流充填;
字符串温度;
int-sameID=0;
open(fileToRead.c_str(),ifstream::in);
if(infle.fail())
返回false;
还有(!infle.eof()){//还有更多吗?好的,我们走吧!
cin.ignore();//我们的计算不需要类ID
getline(infle,temp);//获取学生ID
sameID=isSame(temp,studentInfo);//在我们的ID列表中找到它
如果(sameID!=-1){//如果存在匹配项,则获取字母等级
getline(填充、温度);
学生信息[sameID]。班级成绩。向后推(临时);
}
//没有匹配?忽略。
}
infle.close();
返回true;
}
bool readQueryFile(字符串文件toread,向量studentInfo)
{
河流充填;
int-sameID=0;
字符串温度;
open(fileToRead.c_str(),ifstream::in);
if(infle.fail())
返回false;
else while(!infle.eof()){
getline(填充、温度);
sameID=isSame(temp,studentInfo);//我们得到一个ID,比较它
if(sameID!=-1)//如果它在那里,我们将标记它不报告由于错误导致的GPA为0
studentInfo[sameID]。是否在\u Query=true;
}
infle.close();
返回true;
}
void outputreport文件(字符串fileToWrite,向量studentInfo)
{
出流孔的直径;
open(fileToWrite.c_str(),ifstream::out);
setf(ios::fixed | ios::showpoint);
对于(int x=0;xoutFile您的函数
readStudentFile
直接写入尚未调整大小的向量

在为其编制索引之前,您必须调整其大小:

studentInfo.resize( studentInfo.size() + 1 );
student & record = studentInfo.back();
getline(inFile, record.ID);
getline(inFile, record.name);
getline(inFile, record.address);
getline(inFile, record.phone);
或创建记录并将其追加:

student record;
getline(inFile, record.ID);
getline(inFile, record.name);
getline(inFile, record.address);
getline(inFile, record.phone);
studentInfo.push_back(record);

基于您的代码,您会立即想到两个问题。首先,当您创建一个向量(如
studentList
)时,默认大小和容量均为0。当您访问向量(如
studentList[index]
)时,您正在访问向量末尾之外的内容,并覆盖一些随机内存

如果您知道最大学生数(看起来与您不一样),则可以将向量初始化为
向量studentList(maxNumberOfStudents)
。这将为您提供一个包含maxNumberOfStudent条目的向量,其中每个条目包含所有字段的默认构造版本(对于字符串,它们将为空)。或者,您可以使用类似于
studentList.push_back(student())
的方法将一个新条目附加到向量。您可能可以使用一种更简洁的方法来执行此操作,但这是一般的想法

第二,将
学生列表
向量传递给要通过引用传递的函数(
向量和学生列表
)时。如果没有
&
,则传递的是值,这意味着您每次都在复制向量。由于多个函数修改向量,如果通过值传递,则将