c ++处理来自输入文件的数据会产生无限循环

时间:2016-07-14 02:18:26

标签: c++ arrays file loops

我是C ++的初学者,正在进行一项(据称是简单的)任务,但这让我头痛... ...

我熟悉允许使用动态数组的C#和Java,以及其他整洁的东西,例如foreach循环......

该程序包括从文件中读取数据:

5
Johnson
5000
Miller
4000
Duffy
6000
Robinson
2500
Ashton
1800

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

我基本上想要读取第一行,将其存储在一个变量中,该变量将用作我的循环迭代限制,并将所有名称存储在一个数组中,然后将所有数字存储在第二个数组中以对其进行处理。 / p>

这是我尝试读取文件时创建的一个小测试片段。它有效,但它会产生一个无限循环:(

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 个答案:

答案 0 :(得分:1)

C ++有动态数组(通过std::vector)和foreach循环(通过std::for_each()range-based for loops等)。

尝试更像这样的事情:

#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;
}

答案 1 :(得分:-1)

#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循环运行这个候选人数。对于每个候选人的数量,这样的名称和投票。为了确保一切顺利,我正在打印&#34;你好&#34; numberofcandidates * numberofcandidates次。 希望这会有所帮助。