C++ 程序中的段错误

问题描述 投票:0回答:1

count_words.h

#ifndef _count_words_h_
#define _count_words_h_

#include <string>
#include <list>
#include <map>

class CountWords {
    std::map<std::string, int> countWords;      
        public  :
            CountWords();
            ~CountWords();
            int getCountWord(const std::string& word) const;
            int addWord(const std::string& word);
            const std::list<std::pair<std::string, int>>& getMaxCountWord() const;
            const std::list<std::pair<std::string, int>>& getMinCountWord() const;
};

#endif // _count_words_h_

count_words.c

#include "count_words.h"

CountWords::CountWords() {}

CountWords::~CountWords() {}

int CountWords::getCountWord(const std::string& word) const {
        if(countWords.find(word) != countWords.end()) {
                return countWords.find(word)->second;
        } else {
                return 0;
        }
}

int CountWords::addWord(const std::string& word) {
        return ++countWords[word];
}

const std::list<std::pair<std::string, int>>& CountWords::getMaxCountWord() const {
    std::list<std::pair<std::string, int>> maxCountWords;
        int maxCount = 0;
        
    for(const auto& pair : countWords) {
            if(pair.second > maxCount) {
                    maxCount = pair.second;
            }
        }
        
    for(const auto& pair : countWords) {
            if(pair.second == maxCount) {
                    maxCountWords.push_back(pair);
            }
        }
        return maxCountWords;
}

const std::list<std::pair<std::string, int>>& CountWords::getMinCountWord() const {

}

parse_text.h

#ifndef _parse_text_h_
#define _parse_text_h_

#include <list>
#include <string>
#include <utility>
#include <fstream>

class ParseText {
        std::list<std::string> words;
        std::ifstream file;
        static int currentWord;
        void openFile(const std::string& fileName);
        void parseFile();
        void closeFile();
        public  :
                ParseText() = delete;
                ParseText(const std::string& fileName);
                ParseText(const std::string& fileName, unsigned long long maxWords);
                ~ParseText();
                const std::string& getFirstWord() const;
        const std::pair<std::string, bool>& getNextWord() const;
                const std::string& getWordAt(int index) const;
};

#endif // _parse_text_h_

parse_text.c

#include "parse_text.h"

int ParseText::currentWord = 0;

void ParseText::openFile(const std::string& fileName) {
        file.open(fileName);
}

void ParseText::closeFile() {
        file.close();
}

void ParseText::parseFile() {
        if(!file.is_open()) {
                throw std::runtime_error("couldn't open file");
        }
        std::string word;
        while(file >> word) {
                words.push_back(word);
        }
}

ParseText::ParseText(const std::string& fileName) {
        openFile(fileName);
        parseFile();
}

ParseText::ParseText(const std::string& fileName, unsigned long long maxWords) {
        openFile(fileName);
        parseFile();
        if(maxWords < words.size()) {
                auto it = words.begin();
                std::advance(it, maxWords);
                words.erase(it, words.end());
        }
}

ParseText::~ParseText() {
        closeFile();
}

const std::string& ParseText::getFirstWord() const {
        currentWord = 0;
        if(words.empty()) {
                throw std::runtime_error("no words in the list");
        }
        return words.front();
}

const std::pair<std::string, bool>& ParseText::getNextWord() const {
    if(currentWord >= words.size()) {
        return std::make_pair(std::string(), true);
    }
    ++currentWord;
    bool isLastWord = (currentWord == words.size() - 1);
    auto it = words.begin();
        std::advance(it, currentWord);
    return std::pair(*it, isLastWord);
}

const std::string& ParseText::getWordAt(int index) const {
        if(index < 0 || index >= words.size()) {
                throw std::out_of_range("index out of range");
        }
    auto it = words.begin();
        std::advance(it, index);
    return *it;
}

main.c

#include "parse_text.h"
#include "count_words.h"
#include <iostream>
#include <fstream>
#include <string>

int main() {
    std::string inputFileName = "text.txt"; 
    std::string outputFileName = "result.txt"; 
    
    const ParseText parseText(inputFileName);

    CountWords wordCounter;

    const std::string& firstWord = parseText.getFirstWord();
    wordCounter.addWord(firstWord);

    while (true) {
        const std::pair<std::string, bool>& wordInfo = parseText.getNextWord();
        if (wordInfo.second) {
            break;
        }
        const std::string& word = wordInfo.first;
        wordCounter.addWord(word);
    }

    const std::list<std::pair<std::string, int>>& maxCountWords = wordCounter.getMaxCountWord();
    const std::list<std::pair<std::string, int>>& minCountWords = wordCounter.getMinCountWord();

    std::ofstream outputFile(outputFileName);
    if (outputFile.is_open()) {
        int wordNumber = 1;

        for (const auto& pair : maxCountWords) {
            outputFile << wordNumber << "\t" << pair.first << "\t" << pair.second << "\n";
            wordNumber++;
        }

        for (const auto& pair : minCountWords) {
            outputFile << wordNumber << "\t" << pair.first << "\t" << pair.second << "\n";
            wordNumber++;
        }

        outputFile.close();
    } else {
        std::cerr << "err" << outputFileName << std::endl;
    }

    return 0;

c++中有这样一个程序。它应该计算文本文件中的单词数,并将结果以 №/tword/tcount/n 格式输出到 result.txt 中。似乎所有函数都编写正确,但在 main 行中

const std::pair<std::string, bool>& wordInfo = parseText.getNextWord()
崩溃了段错误。我无法弄清楚这可能与什么有关。根据任务,您无法更改函数的描述,因此我无法使 getNextWord() 函数返回值,而不是链接。 如果您能告诉我 main.c 文件结构有什么问题,我将非常感激 <:

我尝试调试程序,似乎错误在 main 中,而不是在函数本身中,程序崩溃了

c++ segmentation-fault
1个回答
0
投票

您想要做的是返回对列表中字符串的引用以避免复制,操作如下。

std::pair<const std::string&, bool>

接下来的令人厌恶的事情会在函数堆栈上创建一个对一对的悬空引用,该引用在列表中创建字符串的副本....然后它释放字符串和悬空。

const std::pair<std::string, bool>&
© www.soinside.com 2019 - 2024. All rights reserved.