C++ 处理输入文件中的数据会创建无限循环



我是C++的初学者,正在做一项(据说很简单)作业,但这让我头疼......

我熟悉 C# 和 Java,其中允许动态数组,并且存在其他整洁的东西,例如 foreach 循环......

该程序包括从如下所示的文件中读取数据:

5约翰生5000磨坊主4000达 菲6000罗宾逊2500阿什顿1800

第一行始终是"候选人"的数量,后跟重复该候选人的姓名/票数(分别是每行)。该程序限制为 20 个候选者 - 我认为这是因为不允许动态数组,因此我们必须创建固定大小的数组来保存每种类型的数据。

我基本上希望阅读第一行,将其存储在将用作我的循环迭代限制的变量中,并将所有名称存储在一个数组中,然后将所有数字存储在第二个数组中以处理它们。

这是我尝试读取文件时制作的一个小测试片段。它可以工作,但它会生成一个无限循环:(

int main() {
    string candidateNames[21];
    double votesReceivedPerCandidate[21];
    ifstream infile("votedata.txt");
    while (!infile.eof()) {
        string firstLine;
        int numberofCandidates;
        getline(infile, firstLine);
        numberofCandidates = atoi(firstLine.c_str());
        for (int x = 0; x < numberofCandidates; x++) {
            cout << "hello!";
        }
    }
}

我现在睡眠不足,甚至不确定我是否以正确的方式思考这个问题。

我的问题是:

  1. 使用 C++,您将如何只读取第一行,然后将该行中的数字用作for循环中的条件?(另外 - for循环是最好的选择吗?你会如何设置它?)

  2. 您将如何设置上面的循环来读取文件并将一个条目存储到一个数组中,将下一个条目存储到另一个数组中,并成对重复该过程?(就像你发牌给2个人一样)?

C++具有动态数组(通过std::vector)和foreach循环(通过std::for_each(),基于范围的for循环等)。

尝试更多类似的东西:

#include <vector>
#include <string>
#include <fstream>
#include <limits>
struct candidate
{
    std::string name;
    double votes;
};
int main()
{
    std::vector<candidate> candidates;
    std::ifstream infile("votedata.txt");
    int numberofCandidates;
    if (infile >> numberofCandidates)
    {
        infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        for (int x = 0; x < numberofCandidates; x++)
        {
            candidate c;
            if (!std::getline(infile, c.name)) break;
            if (!(infile >> c.votes)) break;
            infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
            candidates.push_back(c);
        }
    }
    // use candidates as needed...
    return 0;
}

如果你真的想变得棘手,你可以让 STL 为你循环访问文件,方法是利用std::copy()std::copy_n()std::istream_iteratorstd::back_inserter 作为输入/输出迭代器:

#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
struct candidate
{
    std::string name;
    double votes;
};
std::istream& operator>>(std::istream &in, candidate &c)
{
    if (std::getline(in, c.name))
    {
        if (in >> c.votes)
            in.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
    }
    return in;
}
int main()
{
    std::vector<candidate> candidates;
    std::ifstream infile("votedata.txt");
    int numberofCandidates;
    if (infile >> numberofCandidates)
    {
        infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        // using std::copy()...
        // ignoring numberofCandidates, read until EOF...
        std::copy(std::istream_iterator<candidate>(infile),
                 std::istream_iterator<candidate>(),
                 std::back_inserter(candidates));
        // using std::copy_n()...
        std::copy_n(std::istream_iterator<candidate>(infile),
                 numberofCandidates,
                 std::back_inserter(candidates));
    }
    // use candidates as needed...
    return 0;
}

考虑到您还没有介绍std::vector,您可能还没有介绍 STL 算法,所以上面看起来更像是这样,使用手动循环和 2 个固定数组而不是 std::vector

#include <string>
#include <fstream>
#include <limits>
const int cMaxCandidates = 20;
int main()
{
    std::string candidateNames[cMaxCandidates];
    double candidateVotes[cMaxCandidates];
    int numberofCandidates = 0;
    std::ifstream infile("votedata.txt");
    int numberofCandidatesInFile;
    if (infile >> numberofCandidatesInFile)
    {
        infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        for (int x = 0; (x < numberofCandidatesInFile) && (x < cMaxCandidates); x++)
        {
            if (!std::getline(infile, candidateNames[x])) break;
            if (!(infile >> candidateVotes[x])) break;
            infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
            ++numberofCandidates;
        }
    }
    // use candidateNames[] and candidateVotes[] up to max
    // numberofCandidates of elements as needed...
    return 0;
}

或者,使用动态分配的数组:

#include <string>
#include <fstream>
#include <limits>
int main()
{
    std::string *candidateNames = NULL;
    double *candidateVotes = NULL;
    int numberofCandidates = 0;
    std::ifstream infile("votedata.txt");
    int numberofCandidatesInFile;
    if (infile >> numberofCandidatesInFile)
    {
        infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
        candidateNames = new std::string[numberofCandidatesInFile];
        candidateVotes = new double[numberofCandidatesInFile];
        for (int x = 0; x < numberofCandidatesInFile; x++)
        {
            if (!std::getline(infile, candidateNames[x])) break;
            if (!(infile >> candidateVotes[x])) break;
            infile.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
            ++numberofCandidates;
        }
    }
    // use candidateNames[] and candidateVotes[] up to max
    // numberofCandidates of elements as needed...
    delete[] candidateNames;
    delete[] candidateVotes;
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main() {
        string candidateNames[21];
        double votesReceivedPerCandidate[21];
        ifstream infile("in.txt");
        int numberofCandidates;
        infile >> numberofCandidates;
        infile.get();
        for(int i = 0; i < numberofCandidates; ++i) {
            getline(infile, candidateNames[i]);
            infile >> votesReceivedPerCandidate[i];
            for (int x = 0; x < numberofCandidates; x++) {
                cout << "hello!" << endl;
            }
            cout << endl;
        }
        return 0;
 }

首先获取候选项数,然后使用 for 循环运行到此候选项数。对于每个候选人的数量,以这种方式取名字和选票。为了确保一切正常,我打印"你好"候选人数*候选人数倍。希望这有帮助。

相关内容

  • 没有找到相关文章

最新更新