0

これが私の最初の投稿です。私はC++での比較的初心者のプログラミングであり、このエラーは私を困惑させました。

私のプログラムは、スペースで区切られたいくつかのテキストファイルから入力を受け取り、csvファイルを吐き出すことになっています。

私のコードは問題なくコンパイルされますが、プログラムがクラッシュし、次のエラーを取得できました。

デバッグ中のプログラムは、GDBから呼び出された関数内で通知されました。GDBは、コンテキストを呼び出し前の状態に復元しました。この動作を変更するには、「unwindonsignalをオフに設定」を使用します。関数(std :: string :: size()const)を含む式の評価は中止されます。プログラム受信信号SIGSEGV、セグメンテーション違反。0x00423576 in 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;
}
4

3 に答える 3

1

addInOrder 関数では:

int toBeMoved = size - 1;
while (toBeMoved >= 0 && value < array[toBeMoved]) {
  array[toBeMoved+1] = array[toBeMoved];   

toBeMovedは、配列の範囲外で、最初の反復でここでサイズになります。

于 2013-02-03T06:15:10.297 に答える
0

Jermaine Xuの答えを拡張する:

解決:

std::vector<T>配列/ポインタの代わりに使用します。動的なサイズ変更と削除を処理します。プログラムもはるかにクリーンになります(おそらくより効率的になります)

于 2013-02-03T06:29:04.830 に答える
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);
  }
}

お役に立てれば!

于 2013-02-03T08:13:30.983 に答える