我是使用C ++和Microsoft Visual Studio的新手,我尝试将数据文件(2列乘500行组成浮点数)转换为数组,然后我尝试在屏幕上输出数组。每当我尝试运行它时,它会在file.exe中的0x001BC864处出现"未处理的异常:0xC0000005:访问冲突写入位置0x00320A20。"
我发现了这段视频并尝试调整该代码https://www.youtube.com/watch?v=4nz6rPzVm70
任何帮助将不胜感激。
#include<stdio.h>
#include<string>
#include<iostream> //
#include<fstream> //
#include<array> //
#include<iomanip> //
#include<sstream>//
#include<conio.h>
using namespace std;
int rowA = 0; //
int colA = 0;
int main()
{
string lineA;
int x;
float arrayA[2][500] = { { 0 } };
ifstream myfile("C:/results.dat");
if (myfile.fail()) {
cerr << "File you are trying to access cannot be found or opened";
exit(1);
}
while (myfile.good()) {
while (getline(myfile, lineA)) {
istringstream streamA(lineA);
colA = 0;
while (streamA >> x) {
arrayA[rowA][colA] = x;
colA++; }
rowA++; }
}
cout << "# of Rows --->" << rowA << endl;
cout << "# of Columns --->" << colA << endl;
cout << " " << endl;
for (int i = 0; i < rowA; i++) {
for (int j = 0; j < colA; j++) {
cout << left << setw(6) << arrayA[i][j] << " ";
}
cout << endl;
}
return 0;
_getch();
}
答案 0 :(得分:2)
显然,您对数组的访问超出范围,因为您的数组索引超出了数组维度的大小。
鉴于这不会是您最后一次遇到此类问题,我的回答将为您提供有关如何检测此类问题是否出错的提示。
您在机架上的第一个工具是向代码添加断言,这会在代码的调试版本中显现问题。
#include <cassert>
// ...
while (myfile.good()) {
while (getline(myfile, lineA)) {
istringstream streamA(lineA);
colA = 0;
while (streamA >> x) {
// probably you would have noticed the error below while writing
// those assertions as obviously you would notice that you want 500
// rows and not 2 and you want 2 columns, not 500...
assert( rowA < 2 ); // <<--- This will assert!
assert( colA < 500 ); // <<--- This will assert if there are more than 500 lines in the file.
arrayA[rowA][colA] = x;
colA++; }
rowA++; }
只有那2条额外的行(和包含),你就可以看到代码混乱的地方。
在这种情况下,修复代码非常简单,我将其作为练习留给您;)
为了避免混淆多维数组的索引,您可以用更具启发性的方式编写代码(更易读)。
int main()
{
string lineA;
int x;
const int NUM_COLUMNS = 2;
const int NUM_ROWS = 500;
float arrayA[NUM_COLUMNS][NUM_ROWS] = { { 0 } };
// ...
这一点额外的表现力增加了你注意到下面你的数组访问使用每个数组维度错误的索引变量的几率。
最后,如果输入文件没有违反您的假设(2列,少于501行),您应该添加额外的检查,因为您的程序只能正常工作(修复后)。这属于“防御性编程”一章 - 即你的代码保护自己免受违反其控制范围之外的假设。
你在底部的打印循环中重复你的错误,顺便说一句。你也可以添加断言。