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()
时,您访问的位置 i
的 grades
是无效的。将您的 if 更改为:
if(i>=grades.size())
您的代码将正常工作。
【讨论】:
顺便说一句,我不知道这是一个练习还是类似的东西,你必须使用所有这些 c 字符串函数和选择排序算法,但是你错过了所有令人惊叹的 c++让您的生活更轻松的功能! 好吧,我知道这听起来令人难以置信,但我昨天遇到了一个使用 Turbo C++ 的人... 我知道对吗?你是新来的。如果你再潜伏一点,你会发现一个完美的答案就是停止使用 Borland C++ XD 我不会在条件中使用>
如果不使用,当i等于grades.size()+1时,代码会进入else指令,同样的问题会再次出现。以上是关于C ++逗号分隔的输入数组代码过早退出的主要内容,如果未能解决你的问题,请参考以下文章