【问题标题】:Issue With Repeating Statement In C++C++ 中重复语句的问题
【发布时间】:2013-12-13 02:52:41
【问题描述】:

(注意:这是问题的更新版本) 所以我正在升级我之前从事的项目。 现在,它将程序的输出打印到文件中,同时组织成绩。 到目前为止,一切都应该正常,除了一个错误。 代码如下:

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

struct Classes
{
    double acousticGuitarEnsemble;
    double biology;
    double english;
    double geometry;
    double hebrew;
    double jewishStudies;
    double worldHistory;
};

void grade1(Classes eitan)
{
    newGrade1:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered1;
    cin >> classBeingEntered1;
    cout << "Enter the new grade: ";
    double grade1;
    cin >> grade1;
    cout << "Grade entered." << endl;
    if (classBeingEntered1 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade1;
    else if (classBeingEntered1 == "biology")
        eitan.biology = grade1;
    else if (classBeingEntered1 == "english")
        eitan.english = grade1;
    else if (classBeingEntered1 == "jewishStudies")
        eitan.jewishStudies = grade1;
    else if (classBeingEntered1 == "geometry")
        eitan.geometry = grade1;
    else if (classBeingEntered1 == "hebrew")
        eitan.hebrew = grade1;
    else if (classBeingEntered1 == "worldHistory")
        eitan.worldHistory = grade1;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade1;
}

void grade2(Classes eitan)
{
    newGrade2:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered2;
    cin >> classBeingEntered2;
    cout << "Enter the new grade: ";
    double grade2;
    cin >> grade2;
    cout << "Grade entered." << endl;
    if (classBeingEntered2 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade2;
    else if (classBeingEntered2 == "biology")
        eitan.biology = grade2;
    else if (classBeingEntered2 == "english")
        eitan.english = grade2;
    else if (classBeingEntered2 == "jewishStudies")
        eitan.jewishStudies = grade2;
    else if (classBeingEntered2 == "geometry")
        eitan.geometry = grade2;
    else if (classBeingEntered2 == "hebrew")
        eitan.hebrew = grade2;
    else if (classBeingEntered2 == "worldHistory")
        eitan.worldHistory = grade2;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade2;
}

void grade3(Classes eitan)
{
    newGrade3:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered3;
    cin >> classBeingEntered3;
    cout << "Enter the new grade: ";
    double grade3;
    cin >> grade3;
    cout << "Grade entered." << endl;
    if (classBeingEntered3 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade3;
    else if (classBeingEntered3 == "biology")
        eitan.biology = grade3;
    else if (classBeingEntered3 == "english")
        eitan.english = grade3;
    else if (classBeingEntered3 == "jewishStudies")
        eitan.jewishStudies = grade3;
    else if (classBeingEntered3 == "geometry")
        eitan.geometry = grade3;
    else if (classBeingEntered3 == "hebrew")
        eitan.hebrew = grade3;
    else if (classBeingEntered3 == "worldHistory")
        eitan.worldHistory = grade3;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade3;
}

void grade4(Classes eitan)
{
    newGrade4:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered4;
    cin >> classBeingEntered4;
    cout << "Enter the new grade: ";
    double grade4;
    cin >> grade4;
    cout << "Grade entered." << endl;
    if (classBeingEntered4 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade4;
    else if (classBeingEntered4 == "biology")
        eitan.biology = grade4;
    else if (classBeingEntered4 == "english")
        eitan.english = grade4;
    else if (classBeingEntered4 == "jewishStudies")
        eitan.jewishStudies = grade4;
    else if (classBeingEntered4 == "geometry")
        eitan.geometry = grade4;
    else if (classBeingEntered4 == "hebrew")
        eitan.hebrew = grade4;
    else if (classBeingEntered4 == "worldHistory")
        eitan.worldHistory = grade4;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade4;
}

void grade5(Classes eitan)
{
    newGrade5:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered5;
    cin >> classBeingEntered5;
    cout << "Enter the new grade: ";
    double grade5;
    cin >> grade5;
    cout << "Grade entered." << endl;
    if (classBeingEntered5 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade5;
    else if (classBeingEntered5 == "biology")
        eitan.biology = grade5;
    else if (classBeingEntered5 == "english")
        eitan.english = grade5;
    else if (classBeingEntered5 == "jewishStudies")
        eitan.jewishStudies = grade5;
    else if (classBeingEntered5 == "geometry")
        eitan.geometry = grade5;
    else if (classBeingEntered5 == "hebrew")
        eitan.hebrew = grade5;
    else if (classBeingEntered5 == "worldHistory")
        eitan.worldHistory = grade5;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade5;
}

void grade6(Classes eitan)
{
    newGrade6:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered6;
    cin >> classBeingEntered6;
    cout << "Enter the new grade: ";
    double grade6;
    cin >> grade6;
    cout << "Grade entered." << endl;
    if (classBeingEntered6 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade6;
    else if (classBeingEntered6 == "biology")
        eitan.biology = grade6;
    else if (classBeingEntered6 == "english")
        eitan.english = grade6;
    else if (classBeingEntered6 == "jewishStudies")
        eitan.jewishStudies = grade6;
    else if (classBeingEntered6 == "geometry")
        eitan.geometry = grade6;
    else if (classBeingEntered6 == "hebrew")
        eitan.hebrew = grade6;
    else if (classBeingEntered6 == "worldHistory")
        eitan.worldHistory = grade6;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade6;
}

void grade7(Classes eitan)
{
    newGrade7:
    cout << "Which grade are you entering? (Use the following format: exampleFormat): ";
    string classBeingEntered7;
    cin >> classBeingEntered7;
    cout << "Enter the new grade: ";
    double grade7;
    cin >> grade7;
    cout << "Grade entered." << endl;
    if (classBeingEntered7 == "acousticGuitarEnsemble")
        eitan.acousticGuitarEnsemble = grade7;
    else if (classBeingEntered7 == "biology")
        eitan.biology = grade7;
    else if (classBeingEntered7 == "english")
        eitan.english = grade7;
    else if (classBeingEntered7 == "jewishStudies")
        eitan.jewishStudies = grade7;
    else if (classBeingEntered7 == "geometry")
        eitan.geometry = grade7;
    else if (classBeingEntered7 == "hebrew")
        eitan.hebrew = grade7;
    else if (classBeingEntered7 == "worldHistory")
        eitan.worldHistory = grade7;
    else
        cout << "Invalid class name. Try again." << endl;
        goto newGrade7;
}

Classes gradeEditor(Classes eitan)
{
    cout << "GradeBook 1.2" << endl;
    grade1(eitan);
    cout << "Editing next grade..." << endl;
    grade2(eitan);
    cout << "Editing next grade..." << endl;
    grade3(eitan);
    cout << "Editing next grade..." << endl;
    grade4(eitan);
    cout << "Editing next grade..." << endl;
    grade5(eitan);
    cout << "Editing next grade..." << endl;
    grade6(eitan);
    cout << "Entering next grade..." << endl;
    grade7(eitan);
    return eitan;
}

void choice(Classes eitan)
{
    choiceBack:
    cout << "Do you want to edit another grade? (If yes, you must reset all the grades) Press Y or N: ";
    char chChoice;
    cin >> chChoice;
    switch (chChoice) {
        case 'Y':
            cout << "Alright then!" << endl;
            do {
            gradeEditor(eitan);
            goto choiceBack; // Refers to beginning of choice() function
            } while (chChoice == 'Y');
        case 'N':
            cout << "Printing grades..." << endl;
            break;
        case 'y':
            cout << "Alright then!" << endl;
            do {
            gradeEditor(eitan);
            goto choiceBack; // Refers to beginning of choice() function
            } while (chChoice == 'y');
        case 'n':
            cout << "Printing grades..." << endl;
            break;
    }
}

void printGrades(Classes eitan)
{
    cout << "Acoustic Guitar Ensemble: " << eitan.acousticGuitarEnsemble << endl;
    cout << "Biology: " << eitan.biology << endl;
    cout << "English: " << eitan.english << endl;
    cout << "Jewish Studies: " << eitan.jewishStudies << endl;
    cout << "Geometry: " << eitan.geometry << endl;
    cout << "Hebrew: " << eitan.hebrew << endl;
    cout << "World History: " << eitan.worldHistory << endl;
    system("PAUSE");
}

int main(Classes eitan)
{
    ofstream outputFile;
    outputFile.open("userGrades.txt");
    gradeEditor(eitan);
    choice(eitan);
    printGrades(eitan);
    outputFile.close();
    cout << "Grades saved to file!" << endl;
    return 0;
}

在 ClassesgradeEditor() 中,我输入了 7 个等级。 但是,它不会在 7 次后停止。 有人知道如何解决吗? - 艾坦 P.S:我知道人们对我使用 goto 有意见。但是我还没有想出在那些特定情况下使用 do while 的方法。所以不要提它,除非你能告诉我一个更好的替代品。 P.P.S: 在这一点上,我不太清楚如何更好地正确格式化我的程序。我确实非常了解编程语法,但现在我懂了。

【问题讨论】:

  • 那些gotos 应该是循环。
  • 在退回之前您还没有接触过eitan。你不断声明局部变量并将它们丢弃。
  • 您一遍又一遍地声明局部变量,并且从不返回它们。例如,在gradeEditor 中声明eitan,永远不要对它做任何事情(在你调用的每个函数中,它们都有自己的副本,它们也会丢弃)然后尝试返回它。
  • 只是开始,而不是grade1到grade7,只有1个等级方法:grade(Classes&amp; class),而不是声明一个局部变量,而是使用传入的class
  • 编辑后仍然损坏。您需要传递一个引用,否则您正在编辑您传递的变量的副本,并且您的 goto 循环似乎都没有结束。

标签: c++ visual-c++ visual-studio-2012


【解决方案1】:

错误信息非常清晰。问题不在于return 关键字。问题是尝试使用变量而不初始化它。

Classes eitan;
//several lines of code in which you do nothing with eitan, then:
return eitan;

如果您尝试执行除return 之外的其他操作,则会遇到相同的错误消息。

如果需要使用main中声明的eitan,则将其作为变量传递。

Classes gradeEditor(Classes& c) {
    //stuff
    return c;
}

然后这样称呼它:

gradeEditor(eitan);

对所有 void 函数执行相同操作。

如果你不想传递变量,但想在多个函数中使用它,那么你必须将它声明为全局变量。简单地创建一个在不同范围内具有相同名称的新变量不会使两个变量指向相同的信息。


你陷入了无限循环,因为:

else
    cout << "Invalid class name. Try again." << endl;
    goto newGrade2;

没有做你认为它做的事。你需要花括号:

else {
    cout << "Invalid class name. Try again." << endl;
    goto newGrade2;
}

【讨论】:

  • 嗯,这是每个人都缺少的。我确实使用 Classes eitan,因为我在每个函数的结构中编辑变量。我只是把它分成不同的功能,以便更好地组织它。
  • 什么?谁错过了什么?
  • @DJHead-On,​​您正在不同的对象中编辑变量。如果在不同函数中本地定义的同名对象实际上都是同一个对象,代码将变得非常难以维护。
  • @chris 我一开始确实是这样,但我解决了这个问题(如果我理解你的意思的话)。
  • @chris 的可维护性不亚于 7 个功能相同的功能或 goto: 语句... ;)
【解决方案2】:

你应该重写你的代码并删除所有的 goto,它被认为是 不好的做法 - 至少在你正在做的那种程序中。

您可以像这样重写choice 函数,还要注意 Classes 通过引用传递,允许对其进行修改。通过它 通过参考,您可以修改它,这是您应该做的 在您修改它的所有功能中执行,否则更改将 保持本地,因为您将副本传递给函数

#include <cctype> // for std::toupper

void choice(Classes& eitan) // pass by reference to modify argument
{
  do
  {
    cout << "Do you want to edit another grade? (If yes, you must reset all the grades) Press Y or N: ";
    char chChoice;
    cin >> chChoice;
    chChoice = std::toupper(chChoice);
    switch (chChoice) 
    {
      case 'Y':
          cout << "Alright then!" << endl;
          gradeEditor(eitan);
          break;
      case 'N':
          cout << "Printing grades..." << endl;
          break;
      default:
          cout << "Please answer Y or N!" << endl;
          break;
    }
  }
  while ( chChoice != 'N' );
}

【讨论】:

  • std::toupper 有什么帮助?它的语法到底是什么?
猜你喜欢
  • 2019-11-26
  • 1970-01-01
  • 2016-11-21
  • 2013-05-31
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多