【问题标题】:How to show message when negative number is entered?输入负数时如何显示消息?
【发布时间】:2019-04-11 00:44:57
【问题描述】:

我遇到了一个问题,当输入负数时,它会显示错误消息。 libc++abi.dylib:以 std::bad_alloc 类型的未捕获异常终止:std::bad_alloc。有没有办法在输入负数并输入消息时检测到该错误:输入 0 或更大。那么,谁能帮我解决这个问题。感谢您的帮助。

我尝试这样做:

int students = 0;
    while (students <= 0) {
     cout << "How many students? ";
        cin >> students;
    if (students <= 0) {
      cout << "Enter 0 or greater"; 
    }
}

  int testsScore = 0;
 while (testsScore <= 0) {
     cout << "How many tests per student? "; 
           cin >> testsScore;
   if (testsScore <= 0) {
     cout << "Enter 0 or greater"; 
    }
}

主代码:

#include <iostream>  // input out stream library. 
#include <iomanip> // parametic manipulators library for our table. 


using namespace std;

//MARK: Structure to use the following data given in the instructions. 
struct student_information {

    //MARK: Student name.
    string studentName; 

    //MARK: Student ID number.
    int id; 

    //MARK: Pointer to an array of test scores.
    int *tests; 

    //MARK:Average test score.
    double average; 

    //MARK: Course grade.
    char grade; 

   };

//MARK: The main() method should keep a list of test scores for group of students. 
int main() {

    // MARK: Declare variables. 
    int numberOfStudents; 
    int testScores; 

    //MARK: So, in our logic it should ask the user how many test scores there are to be, 
    // and how many students there are. 
    // It should then dynamically allocate an array of structures. However, 
    // each structure tests member should point to a dynamically allocated array
    // that will hold the test scores according to our instructions. 

    cout << "How many students?"; 
    cin >> numberOfStudents; 
    cout << endl; 

     cout << "How many tests per student? "; 
    cin >> testScores; 
    cout << endl;





   student_information *pointerToArray = new student_information[numberOfStudents];

    for (int i = 0; i < numberOfStudents; i++) {

        pointerToArray[i].tests = new int[testScores];

    }




    //MARK: So, this is when the array has been allocated, 
    //the program should ask for the student ID number and all the scores for each 
    // every student. 
    for (int i = 0; i < numberOfStudents; i++) {

        cout << "Student Name: "; 
        cin >> pointerToArray[i].studentName;
        cout << endl; 



        cout << "ID Number: "; 
        cin >> pointerToArray[i].id; 
        cout  << endl;





        for (int v = 0; v < testScores; v++)  {
            cout << " Test # " << (v + 1) << " : "; 


            //MARK: Checking to see all the data is entered for each student / member. 
            cin >> pointerToArray[i].tests[v];
            cout << endl; 

            // MARK: Checking if negative numbers  are entered for any test scores. 
            while(pointerToArray[i].tests[v] < 0 || pointerToArray[i].tests[v] > 100)  {

                cout << "Enter 0 or greater"; 
                cin >> pointerToArray[i].tests[v]; 
               cout << endl; 

            }















       }
    }
    //MARK: The average test score should be calculated and stored in the average member of each structure. 
    //The course grade should be computed on the basis of the following grading scale:
    // Average Test Grade     Course Grade
    // 91-100                          A
    // 81-90                           B
    // 71-80                           C
    // 61-70                           D
    // 60 or below                     F

    for (int i = 0; i < numberOfStudents; i++) {

        double add = 0; 

      for(int x=0; x < testScores; x++)
        add = add + pointerToArray[i].tests[x];
        pointerToArray[i].average = add / testScores;

        //MARK: The course grade will be stored in the grade member structure.
        //After the data entry has been calculated.
    if(pointerToArray[i].average >= 91 && pointerToArray[i].average <= 100)
        pointerToArray[i].grade = 'A';

     else if(pointerToArray[i].average >= 81 && pointerToArray[i].average <= 90)
        pointerToArray[i].grade = 'B';

     else if(pointerToArray[i].average >= 71 && pointerToArray[i].average <= 80)
        pointerToArray[i].grade = 'C';

     else if(pointerToArray[i].average >= 61 && pointerToArray[i].average <= 70)
        pointerToArray[i].grade = 'D';

     else if(pointerToArray[i].average < 60)
        pointerToArray[i].grade = 'F';



        //MARK: Displaying the table to list each students name, ID number, 
         //average test score and the course grade.

        for(int i=0; i < numberOfStudents; i++)
        {

         cout << "Student Name: " << setw(19) << left << pointerToArray[i].studentName <<
         " ID Number: " << setw(19) << pointerToArray[i].id <<
         " Average test score: " <<  setw(15) << pointerToArray[i].average <<
         " Grade: " << setw(15) << pointerToArray[i].grade << endl;

        }


        return 0;

    }



    }

【问题讨论】:

  • 当您尝试解决方案时发生了什么?它没有工作吗?请提供minimal reproducible example
  • 您的代码看起来很混乱。请让您的 IDE 或编辑器格式化代码。之后,前两行中的ifwhile 将在同一列中开始。
  • 附带说明:手动调用new 通常是个坏主意。在这种情况下,我建议使用std::vector 而不是手动内存管理。

标签: c++


【解决方案1】:

如果为numberOfStudentstestsScore 输入负数,则

student_information *pointerToArray = new student_information[numberOfStudents];

pointerToArray[i].tests = new int[testScores];

尝试分配大量内存。当这失败时 std::bad_allocthrown 而 OP 不是 catch 它。因此,它在 OPs main() 之外被捕获。

new[] 中的数组大小需要 size_t → 一个无符号值,并静默转换提供的有符号值。例如。 -1 变为 0xffffffff(32 位)甚至更大。

#include <iostream>
#include <iomanip>

int main(int argc, char* argv[])
{
  int value = -1;
  size_t size = value;
  std::cout << "size: " << size << " = 0x" << std::hex << size << '\n';
  try {
    int *mem = new int[size];
  } catch (const std::exception &error) {
    std::cerr << error.what() << '\n';
  }
  return 0;
}

输出:

size: 18446744073709551615 = 0xffffffffffffffff
std::bad_array_new_length

Live Demo on coliru

OP 应添加检查输入数字是否为&gt; 0


我的样本 throws std::bad_array_new_length(而不是 OP 报告的 std::bad_alloc)让我有点困惑。调查了一下,我发现了

  1. 以这种方式精确记录(例如在 cppreference.com 中)

    否则,new-expression 不会调用分配函数,而是抛出 std::bad_array_new_length 类型的异常或从它派生的异常

  2. std::bad_array_new_length 派生自 std::bad_alloc

【讨论】:

  • 我认为 Asker 已经想通了。这就是他们在第一段代码中试图做的事情。可惜他们在尝试时没有更详细地说明出了什么问题。如果他们尝试过。
  • @user4581301 我的第一反应是写评论。前几天,其他人写的和接受的答案一样。因此,我今天试试运气。 ;-)
【解决方案2】:

假设您尝试向学生输入负数并测试分数,您只需要添加一个类似的 while 循环来测试它们,就像您在下面测试成绩一样......

cout << "How many students?";
cin >> numberOfStudents;
while (numberOfStudents <= 0) {
   cout << "Number of students should be greater than 0";
   cin >> numberOfStudents;
   cout << endl;
 }
cout << endl;

如前面的 cmets 所述,new[] 需要 size_t,表示无符号数 https://en.cppreference.com/w/cpp/types/size_t

【讨论】:

  • 感谢您的回答。欣赏它。
猜你喜欢
  • 2019-10-05
  • 1970-01-01
  • 2014-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多