【问题标题】:C++ for loop ends after inputC++ for 循环在输入后结束
【发布时间】:2021-12-04 04:26:05
【问题描述】:
#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    string hometown;
    int age;
    int games;
    int* hours = new int [games];
};

int main(){
    int players;
    Student* s = new Student [players];

    cout << "How many esports players are there at TTU who major in csc?\n";
    cin >> players;
    cout << "\nPlease enter in information about each player: \n\n";

    for(int i = 0; i < players; i++){
        cout << "PLAYER " << (i + 1) << ":\n";
        cout << "\tNAME:\t";
        getline(cin >> ws, s[i].name);
        cout << "\tHOMETOWN:\t";
        getline(cin >> ws, s[i].hometown);
        cout << "\tAGE:\t";
        cin >> s[i].age;
        cout << "\tHOW MANY GAMES DOES " << s[i].name << " PLAY?\t";
        cin >> s[i].games;
            for(int j = 0; j < s[i].games; j++){
                cout << "NUMBER OF HOURS " << s[i].name << "PLAYED GAME"  << (j + 1) << "\t";
                cin >> s[i].hours[j];
            }
    } 

    return 0;
}

由于某种原因,for 循环在询问年龄后结束。我尝试了多个输入,它做同样的事情。我是 C++ 新手。有谁知道为什么?感谢您的宝贵时间

【问题讨论】:

  • 开启编译器警告。考虑到它如何使用未初始化的成员变量默认分配 hours 数组,您的结构在我看来非常粗略。在调试器中运行您的程序,以便在崩溃的代码行上获得一个断点(假设这是一个崩溃,这很可能)。您正在做一些奇怪的事情,还将基于行的输入与格式化的流输入混合在一起,但这可能不是现在的主要问题。
  • 这里,let's look at the compiler warnings。打开和阅读编译器警告可能比寻求帮助要快得多。与new Student [players] 对应的players 的值是多少?
  • "for 循环在询问年龄后结束。" -- 更准确地说,程序 在询问年龄后结束(崩溃) .在你得出只有循环结束的结论之前,你应该测试这个假设。在循环之后放一些输出,可能是cout &lt;&lt; "Program done\n";,这样你就可以看到循环结束和程序结束之间的区别。 (在调试器中运行将是另一种查看差异的方法。)
  • std::vector 类在 C++ 中正式存在了将近 24 年。为什么还有人使用new[]??
  • @Swift-FridayPie -- 我认为 24​​ 年的时间足以让我们看到向量是 C++ 的一部分。或者教学生C,别再骗他们说他们正在学习 C++。

标签: c++ for-loop


【解决方案1】:

您没有正确处理数组。您正在使用未初始化的变量来分配它们的大小:

  • int games; int* hours = new int [games]; 中,games 未初始化。
  • int players; Student* s = new Student [players]; 中,players 未初始化。

而且,即使你正确地分配了数组,你也会泄漏它们,因为当你用完它们时你并没有释放它们。

当你需要使用一个直到运行时才知道大小的数组时,你使用new[]是正确的,但是直到你确定了大小之后,例如:

#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    string hometown;
    int age = 0;
    int games = 0;
    int* hours = nullptr;
};

int main(){
    cout << "How many esports players are there at TTU who major in csc?\n";

    int players;
    cin >> players;

    Student *s = new Student[players];

    cout << "\nPlease enter in information about each player: \n\n";

    for(int i = 0; i < players; ++i){
        cout << "PLAYER " << (i + 1) << ":\n";
        cout << "\tNAME:\t";
        getline(cin >> ws, s[i].name);
        cout << "\tHOMETOWN:\t";
        getline(cin >> ws, s[i].hometown);
        cout << "\tAGE:\t";
        cin >> s[i].age;
        cout << "\tHOW MANY GAMES DOES " << s[i].name << " PLAY?\t";
        cin >> s[i].games;
        s[i].hours = new int[s[i].games];
        for(int j = 0; j < s[i].games; ++j){
            cout << "NUMBER OF HOURS " << s[i].name << " PLAYED GAME " << (j + 1) << "\t";
            cin >> s[i].hours[j];
        }
    }

   // use player info as neded...

    for(int i = 0; i < players; ++i){
        delete[] s[i].hours;
    }
    delete[] s;

    return 0;
}

话虽如此,您应该手动使用std::vector 而不是new[]/delete[],例如:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Student {
    string name;
    string hometown;
    int age = 0;
    int games = 0;
    std::vector<int> hours;
};

int main(){
    cout << "How many esports players are there at TTU who major in csc?\n";

    int players;
    cin >> players;

    std::vector<Student> s(players);

    cout << "\nPlease enter in information about each player: \n\n";

    for(int i = 0; i < players; ++i){
        cout << "PLAYER " << (i + 1) << ":\n";
        cout << "\tNAME:\t";
        getline(cin >> ws, s[i].name);
        cout << "\tHOMETOWN:\t";
        getline(cin >> ws, s[i].hometown);
        cout << "\tAGE:\t";
        cin >> s[i].age;
        cout << "\tHOW MANY GAMES DOES " << s[i].name << " PLAY?\t";
        cin >> s[i].games;
        s[i].hours.resize(s[i].games);
        for(int j = 0; j < s[i].games; ++j){
            cout << "NUMBER OF HOURS " << s[i].name << " PLAYED GAME " << (j + 1) << "\t";
            cin >> s[i].hours[j];
        }
    } 

    // use player info as needed...

    return 0;
}

【讨论】:

  • 非常感谢您的帮助!对此,我真的非常感激。我的教授一直告诉我使用“new”和“malloc”,但我发现 vector 更方便
  • @tntcastle 显然,这也可以使用new[]malloc() 来解决(虽然你真的不应该在C++ 中使用malloc()),但是你有责任释放使用完毕后手动记忆。我已经更新了我的答案以显示这一点。但是std::vector 会为您处理。
  • @tntcastle 的主要问题是无法跟踪在deletedelete[] 之后使用哪个,除非您使用RAII,即您必须编写std::vector 的模拟:结构应该变为非平凡的 - 获取构造函数和析构函数 - 并分配\重新分配\释放其内存。在 C++ 中,malloc 在以后没有放置 new 时几乎没有用处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2019-03-19
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多