繁体   English   中英

读取文本文件时出现分段错误

[英]Segmentation fault when reading text file

我正在尝试运行一个代码,从文本文件中对泰坦尼克号幸存者的年龄进行排序。 它编译得很好,但是当我选择选项 B(选项 A 尚未编写)时,程序终止只是说“分段错误”。这是一个文本文件的小样本供参考。

29 1stClass 真

0.9 1stClass 真

2 一等错

30 一等错

我已将错误隔离到处理文件的块(//实际处理),但我不确定到底是什么错误。

#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <fstream>
#include <ctype.h>

void sortSurvivors();
void sortAgesLiving();

int main()
{
    char options;
    std::cout << "Titanic Data \nOptions \nA) Display count of people who lived and died... \nB) Display count of people who lived by age... \nPlease select option (A-B)...";
    std::cin >> options;
    switch (options)
    {
        case 'A':
            sortSurvivors();
            break;
        case 'B':
            sortAgesLiving();
            break;
    }
}

void sortSurvivors()
{

}

void sortAgesLiving()
{
    std::ifstream inputFile;
    std::string filename = "TitanicData.txt";
    std::string age;
    std::string classBoat;
    std::string survival;
    bool survived;
    int eldest = 0;

    //pre-sort processing
    while (inputFile >> age >> classBoat >> survival)
    {
        int ageConv = stoi(age);
        //G is for the ghetto fix I am pulling here, because I recieve an error when using "TRUE" as a string
        char gchar = 'G';
        survival += gchar;
        if (survival == "TRUEG")
        {
            survived = true;
        }
        else
        {
            survived = false;
        }
        if (eldest < ageConv) 
        {
            eldest = ageConv;
        }
    }

    //initialize vector
    std::vector<int> survivorVector;
    for (int i = 0; i < eldest; i++)
    {
        survivorVector.push_back(0);
    }

    inputFile.open(filename);
    //actual processing (ERROR HERE)
    if (inputFile)
    {
        while (inputFile >> age >> classBoat >> survival)
        {
            int ageConv = stoi(age);

            if (survived = true)
            {
                survivorVector[ageConv] = survivorVector[ageConv] + 1;
            }
            for (int j = 0; j <= eldest; j++)
            {
                std::cout << j << "\t" << survivorVector[j] << "\n";
            }
        }

        // Close the file.
        inputFile.close();
    }
    else
    {
        std::cout << "I don't know what broke, but uhhhhhhhhhh oops.";
    }
}

像往常一样,我确定这是我忽略的一些愚蠢的事情。

sortAgesLiving()中,您忘记在开始预排序处理之前打开文件。 结果,您的第一个阅读循环将根本无法阅读任何内容。 因此, eldest将保持为 0。

然后构建一个向量并填充它。 但由于循环基于eldest ,向量survivorVector将保持为空。

当您最终打开文件并阅读它时,第一行将被视为幸存者,因为您不小心将 boolean 覆盖为 true(即if (survived = true)而不是if (survived == true)或简单地if (survived) . 然后,您将尝试越界访问向量。

即使你纠正了这个错误,在第一个幸存者时你也会再次出界。 越界访问向量是 UB,许多可能的症状之一可能是分段错误。

其他建议(与您的问题无关)

  • 你有一个模糊的年龄0.9 将其转换为int会导致它为 0。这样可以吗,还是需要四舍五入?
  • 如果四舍五入,您可以将年龄变量设置为double并直接读取它而无需转换。 然后,您可以在数学上将其转换为 integer 年龄,根据需要将其向上舍入或截断。 如果您确定只有整数,则可以将变量设置为int而完全不用担心。
  • 信任文件中的值直接索引向量是不安全的。 如果在两个读取阶段之间,其他人会在文件中添加一个值高于eldest的附加行怎么办? 如果读取的值为负数怎么办? 在将值用作索引之前,最好始终检查它是否在可接受的范围内。 它可以为您节省数小时的调试时间,并为您的客户节省一些噩梦。
  • 最后,不需要两阶段读取:您可以只读取年龄,在检查它是否为正且小于 150 岁(非常乐观)之后,如果需要,您可以在年龄相等或大于当前向量大小。 为什么? 想象一下,有一天你为美国人口普查工作,文件有数百万行:文件越少越好;-)

暂无
暂无

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

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