这是我在这里的第一篇文章。我是C ++中相对新手编程的人,这个错误令我感到难过。
我的程序应该从几个空格分隔的文本文件中获取输入并吐出一个csv文件。
我的代码编译得很好,但程序崩溃了,我能够检索到以下错误:
正在调试的程序在从GDB调用的函数中发出信号。 GDB已将上下文恢复到调用之前的状态。 要更改此行为,请使用“set unwindonsignal off”。 评估包含该功能的表达 (std :: string :: size()const)将被放弃。 程序接收信号SIGSEGV,分段故障。 0x00423576在std :: string :: size()const()
中错误发生在此代码的第16行:
#include "arrayUtils.h"
#include "enrollment.h"
#include <string>
#include <iostream>
using namespace std;
/*
* Read the course names and max enrollments. Keep the courses
* in alphabetic order by course name.
*/
void readCourses (istream& courseFile, int numCourses,
string* courseNames, int* maxEnrollments)
{
string courseNameValue = ""; // PROBLEMS START HERE
int maxEnrollmentValue = 0;
while (courseFile){
courseFile >> courseNameValue;
addInOrder(courseNames, numCourses, courseNameValue); //PROGRAM CRASHES HERE
courseFile >> ws;
courseFile >> maxEnrollmentValue;
addInOrder(maxEnrollments, numCourses, maxEnrollmentValue);
}
}
/*
* Read the enrollment requests, processing each one and tracking
* the number of students successfully enrolled into each course.
*/
void processEnrollmentRequests (istream& enrollmentRequestsFile,
int numCourses,
string* courseNames,
int* maxEnrollments,
int* enrollments)
{
// Start the enrollment counters at zero
for (int pos = 0; pos < numCourses; ++pos)
{
enrollments[pos] = 0;
}
// Read the requests, one at a time, serving each one
string courseName;
int courseIndex = 0;
enrollmentRequestsFile >> courseName;
while (enrollmentRequestsFile) {
enrollmentRequestsFile >> ws;
string studentName;
getline (enrollmentRequestsFile, studentName);
courseIndex = binarySearch(courseNames, numCourses, courseName);
if (courseIndex >= 0)
{
if (maxEnrollments[courseIndex] >= enrollments[courseIndex])
{
++enrollments[courseIndex];
cout << studentName << " has enrolled in " << courseName << "\n";
}
else
{
cout << studentName << " cannot be enrolled in " << courseName << "\n";
}
}
else
{
cout << studentName << " cannot be enrolled in " << courseName << "\n";
}
enrollmentRequestsFile >> courseName;
}
}
/*
* Write a CSV report listing each course and its enrollment.
*/
void generateReport (ostream& reportFile,
int numCourses,
string* courseNames,
int* enrollments)
{
for (int pos = 0; pos < numCourses; ++pos)
{
reportFile << "\"" << courseNames[pos] << "\"," << enrollments << "\n";
}
}
void processEnrollments (istream& courseFile, istream& enrollmentRequestsFile,
ostream& reportFile)
{
int numCourses = 0;
int arraySize = 0;
courseFile >> numCourses;
arraySize = numCourses + 1;
// Create the arrays we need
string courseNames[arraySize];
int maxEnrollments[arraySize];
int enrollments[arraySize];
// Process the enrollments
readCourses (courseFile, numCourses, courseNames, maxEnrollments);
processEnrollmentRequests (enrollmentRequestsFile, numCourses,
courseNames, maxEnrollments, enrollments);
generateReport (reportFile, numCourses, courseNames, enrollments);
}
我调用的用于组织字符串数组的函数是:
// Assume the elements of the array are already in order
// Find the position where value could be added to keep
// everything in order, and insert it there.
// Return the position where it was inserted
// - Assumes that we have a separate integer (size) indicating how
// many elements are in the array
// - and that the "true" size of the array is at least one larger
// than the current value of that counter
template <typename T>
int addInOrder (T* array, int& size, T value)
{
// Make room for the insertion
int toBeMoved = size - 1;
while (toBeMoved >= 0 && value < array[toBeMoved]) {
array[toBeMoved+1] = array[toBeMoved];
--toBeMoved;
}
// Insert the new value
array[toBeMoved+1] = value;
++size;
return toBeMoved+1;
}
请帮忙!我不知道该怎么做才能解决这个问题,该计划即将推出!
编辑:
主程序如下:
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include "enrollment.h"
using namespace std;
int main (int argc, char** argv)
{
if (argc != 4)
{
cerr << "Usage: " << argv[0] << " courseFile enrollmentFile reportFile" << endl;
return -1;
}
// Take input and output file names from the command line
ifstream coursesIn (argv[1]);
ifstream enrollmentIn (argv[2]);
ofstream reportOut (argv[3]);
processEnrollments (coursesIn, enrollmentIn, reportOut);
coursesIn.close();
enrollmentIn.close();
reportOut.close();
return 0;
}
答案 0 :(得分:1)
在addInOrder函数中:
int toBeMoved = size - 1;
while (toBeMoved >= 0 && value < array[toBeMoved]) {
array[toBeMoved+1] = array[toBeMoved];
toBeMoved 在第一次迭代中变为 size ,超出了数组范围。
答案 1 :(得分:0)
扩展Jermaine Xu的回答:
解决方案:
使用std::vector<T>
而不是数组/指针。它负责动态调整大小和移除..你的程序也会更清晰(也可能更高效)
答案 2 :(得分:0)
您没有正确使用addInOrder
功能。
string courseNames[numCourses + 1];
courseNames数组定义如上,然后直接将courseName
和numCourses
传递给addInOrder
。在addInOrder
中你做了:
courseName[numCourses] //toBeMoved = size - 1; toBeMoved+1
您从courseName
数组边界访问的内容实际上是访问last element of courseName
。
因此,您需要一个额外的变量来记住您当前的数组大小。像这样:
void readCourses (istream& courseFile, int numCourses,
string* courseNames, int* maxEnrollments)
{
string courseNameValue = "";
int maxEnrollmentValue = 0;
int index = 0; // index to how many real courses are added to courseName array
while (courseFile){
if (index == numCourses){ // courseName array is full, break out
break;
}
courseFile >> courseNameValue;
addInOrder(courseNames, index , courseNameValue); // pass in index, not array size
courseFile >> ws;
courseFile >> maxEnrollmentValue;
addInOrder(maxEnrollments, numCourses, maxEnrollmentValue);
}
}
希望这有帮助!