簡體   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