C ++逗号分隔的输入数组代码过早退出

Posted

技术标签:

【中文标题】C ++逗号分隔的输入数组代码过早退出【英文标题】:C++ Comma Separated Input Array Code Exiting Prematurely 【发布时间】:2020-06-27 19:21:25 【问题描述】:

我正在尝试创建 C++ 代码以获取用逗号分隔的用户输入并将其输入到 int 数组中,然后使用偶数列对其进行排序。出于某种原因,当我将它输入数组时,程序关闭了我。我什至不能让它打印数组,我不太清楚为什么。

样本:

Welcome to Please Help Me Sort Grades!!! :)
Please enter student grades:10,20,30,10,20,30,50,90,10,50

Unsorted:
  Grade  ID
     10   1
     20   2
     30   3
     10   4
     20   5
     30   6
     50   7
     90   8
     10   9
     50  10

Sorted:
  Grade  ID
     10   1
     10   4
     10   9
     20   2
     20   5
     30   3
     30   6
     50   7
     50  10
     90   8

Process finished with exit code 0

代码:

#include <iostream>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>

using namespace std;
// Global Variables and Libraries are declared


using namespace std;


int main() 

    cout << setprecision(20) << fixed;

    int size = 30;
    int StudentID[size];
    int StudentGrades[size];
    string commaList;
    vector<int> grades;
    int MinGrade;
    int MinID;

    //char * token is a char pointer. We will discuss them in a later chapter
    char *token = NULL;

    cout << "Please enter a comma separated list of grades: ";
    getline(cin, commaList);
    //character array that will hold comma seperated list after its copied over
    char gradesCharArr[commaList.size()];
    strcpy(gradesCharArr, commaList.c_str());
    //gives you the location of the first ',' thats encountered in the array
    token = strtok(gradesCharArr, ",");
    //Iterate through each "," that is found until there are none left
    while(token != NULL)
        //convert the grade from a string to an int and push it into the vector
        grades.push_back(stoi(token));
        //find next occurrence of ","
        token = strtok(NULL, ",");
    

    for(int i = 0; i < size; i++)
        if(i > grades.size())
            StudentGrades[i] =0;
            StudentID[i] = 0;
        
        else 
            StudentGrades[i] = grades.at(i);
            StudentID[i] = i + 1;
        
    

    cout << "Unsorted: " << endl;
    //Print grades back to show they are properly tokenized
    for(int i = 0; i < grades.size(); i++)
        cout << StudentGrades[i] << setw(10) << StudentID[i] << endl;
    

    for(int i = 0; i < size; i++)                                               // for the first initial round where we will put the official
                                                                               // max number when found (i)
        for(int j = i + 1; j < size; j++)                                       // for the second subround (j) here the code is comparing the max
                                                                               // value of the array at j and the array at i until we get
            if(StudentGrades[j] < StudentGrades[i])                                         // the ultimate max number. In order to do that though we will
                                                                               // shift the values up one place in the Array and place the
                MinGrade = StudentGrades[i];                                        // max number in it's proper place in MyArray.
                MinID = StudentID[i];
                StudentGrades[i] = StudentGrades[j];
                StudentID[i] = StudentID[j];
                StudentGrades[j] = MinGrade;
                StudentID[j] = MinID;
            
        
    

    cout << "Sorted:" << endl;
    for(int i = 0; i < grades.size(); i++)
        cout << StudentGrades[i] << setw(20) << StudentID[i] << endl;
    

    return 0;

提前非常感谢你:)

【问题讨论】:

他们的意思是:int StudentID[size]; 在标准 c++ 中是不允许的。当您需要动态大小的数组时,请使用 std::vector RE:For some reason when I feed it into the array the program shuts on me... 调试器产生了什么结果? 它是一些编译器的扩展。您需要阅读您的编译器手册以了解它是如何工作的,以及您可以使用它们做什么以及不可以做什么。您既没有指定您正在使用的编译器,也没有使用 C++ 的每个人都知道可变长度数组的所有细节(但他们确实知道std::vector)。详情见这里:Why aren't variable-length arrays part of the C++ standard? 嗯...另外,您提供的代码甚至无法在 MVCC 中编译... 由于不安全的编程实践,显示的代码至少有一个与缓冲区/数组溢出相关的明显错误。由于混合了 C 和 C++ 风格的字符串处理,并且未能考虑 C-样式终止\0。这会导致内存损坏和未定义的行为。你有a good C++ textbook 有如何正确处理 C++ 中的字符串的例子吗? 【参考方案1】:

Mateus Melo 发现的错误是正确的。 for 循环中还有一个用于排序项目。两个语句的大小都应该是 grades.size() 以便在此处正确排序

  for (int i = 0; i < size; i++)                                               // for the first initial round where we will put the official
                                                                             // max number when found (i)
    for (int j = i + 1; j < size; j++)                                       // for the second subround (j) here the code is comparing the max

用 grades.size() 替换应该会产生预期的结果:)

使用此代码也可以更好地接受输入

  cout << "Please enter a comma separated list of grades: ";
  getline(cin, commaList);
  size_t as = commaList.size();
  //character array that will hold comma seperated list after its copied over
  char* gradesCharArr = new char[as+1]();// [a /*commaList.size()*/] ;
  commaList.copy(gradesCharArr, commaList.size());

【讨论】:

【参考方案2】:
for(int i = 0; i < size; i++)
    if(i >= grades.size())
        StudentGrades[i] =0;
        StudentID[i] = 0;
    
    else 
        StudentGrades[i] = grades.at(i);
        StudentID[i] = i + 1;
    

这就是问题所在。你看,C++ 中的索引以0 开头。因此,当您的i 变为grades.size() 时,它超出了vector 的范围。这就是调试器基本上通过错误告诉你的内容:

 __throw_out_of_range_fmt(__N("vector::_M_range_check: __n " "(which is %zu) >= this->size() " "(which is %zu)"), __n, this->size()); 

因此,您需要将该条件更改为:

if(i==grades.size())


另外,附带说明一下,当您使用矢量索引时,最好使用 size_t 而不是普通的旧 int,因为所有矢量函数都需要 size_t,如果他们没有找到,他们会给出通常的溢出错误

希望这会有所帮助:)

【讨论】:

【参考方案3】:

在您的第一个 for 循环中,当 i 等于 grades.size() 时,您访问的位置 igrades 是无效的。将您的 if 更改为:

    if(i>=grades.size())

您的代码将正常工作。

【讨论】:

顺便说一句,我不知道这是一个练习还是类似的东西,你必须使用所有这些 c 字符串函数和选择排序算法,但是你错过了所有令人惊叹的 c++让您的生活更轻松的功能! 好吧,我知道这听起来令人难以置信,但我昨天遇到了一个使用 Turbo C++ 的人... 我知道对吗?你是新来的。如果你再潜伏一点,你会发现一个完美的答案就是停止使用 Borland C++ XD 我不会在条件中使用&gt; 如果不使用,当i等于grades.size()+1时,代码会进入else指令,同样的问题会再次出现。

以上是关于C ++逗号分隔的输入数组代码过早退出的主要内容,如果未能解决你的问题,请参考以下文章

C读取以逗号分隔的数字文件

怎样在c语言中输入不少于10个数字的数组,急求

数组中多个 if 语句的 VBA 代码

js数组相加

如何将在一行中输入的以逗号分隔的数字放入Java中的数组中

将逗号分隔的字符串拆分为数组?