-3

这是我拥有的编程任务的代码。当我运行程序“STRUCT2.EXE 中 0x772BC41F 处的未处理异常:Microsoft C++ 异常:内存位置 0x0043ED04 处的 std::out_of_range”程序时出现此错误。如果我理解正确,则错误意味着我的数组已超出分配的内存空间。那是对的吗?如果这是正确的,我做错了什么?我的输入文件中的元素少于 30 个。

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
#include <sstream>
#include <cctype>
 using namespace std;

struct Element
{
string Name;
char eN1;
char eN2;
float Weight;
};

struct Formula
{
char Element1;
char ElementA;
int Atom;
 };

void ELEMENTS(Element ElmAry[30]);
float Str2Float(string Weight);
void FORMULAS(Formula FormAry[30]);
float CalculateMoleculeWeight(Element ElmAry[30], Formula FormAry[30]);

int main()
{
ifstream inputFile1;
ifstream inputFile2;
ofstream outputFile;

inputFile1.open("Element.txt");
inputFile2.open("Formula.txt");
outputFile.open("Molecular Weight.txt");

Element ElmAry[30];
Formula FormAry[30];
char inputCh;
int i = 0;
string String1;
string mFor;
string ABRV;
int ElmDigit = 0;
float StringWeight = 0;
string Name;
string Weight;
int LENGTH = 0;
float MOLEWT;


if(!inputFile1)
{
    cout << "Couldn't find the Element.txt file." << endl;
    return 0;
}

if(!inputFile2)
{
    cout << "Couldn't find the Formula.txt file." << endl;
    return 0;
}

ELEMENTS(ElmAry);

while(inputFile1)
{
    Name = String1.substr(0,2);
    ElmAry[i].Name = Name;

    Weight = String1.substr(3,10);
    String1.clear();
    StringWeight = Str2Float(Weight);
    ElmAry[i].Weight = StringWeight;
    i++;
}
i--;

FORMULAS(FormAry);

while (inputFile2)
{
    getline(inputFile2,String1);
    LENGTH = String1.length();
    int j = 0;
    int n = 0;
    while( j < LENGTH)
    {
        int pos = 0;
        pos = String1.find(')');
        while(n < LENGTH)
        {
            inputCh = String1.at(n);
            if(isalpha(inputCh) && isupper(inputCh))
            {
                FormAry[j].Element1 = String1.at(n);
                n++;
                inputCh = String1.at(n);
            }

            if(isalpha(inputCh) && islower(inputCh))
            {
                FormAry[j].ElementA = String1.at(n);
                n++;
                inputCh = String1.at(n);
            }

            if(ispunct(inputCh))
            {
                n++;
                inputCh = String1.at(n);
                ElmDigit = (inputCh-'0');
            }

            if(isdigit(inputCh))
            {
                FormAry[j].Atom = ElmDigit;
                n++;
            }
            inputCh = String1.at(n);

            j++;

            if(iscntrl(inputCh))
            {
                n++;
                inputCh = String1.at(n);
                j++;
            }
            n++;
        }
    }
}

MOLEWT = CalculateMoleculeWeight(ElmAry, FormAry);

cout << "\t\t MOLECULAR WEIGHT CHART \t\t\n" << endl;
cout << "\n| FORMULA |\t " << "\t| ATOM.WT |" << endl;
cout << "_______________________________";
outputFile << "\t\t MOLECULAR WEIGHT CHART \t\t\n" << endl;
outputFile << "\n| FORMULA |\t " << "\t| ATOM.WT |" << endl;
outputFile << "_______________________________";

for (int a = 0; a < 30; a++)
{
    cout << MOLEWT << endl;
    outputFile << MOLEWT << endl;
}

inputFile1.close();
inputFile2.close();
outputFile.close();
cin.get();
cin.get();
return 0;
}

void ELEMENTS(Element ElmAry[30])
{
for(int i = 0; i < 30; i++)
{
    ElmAry[i].Weight = 0;
}
}

void FORMULAS(Formula FormAry[30])

{
for(int x = 0; x < 30; x++)
{
    for(int x = 0; x < 9; x++)
    {
        FormAry[x].Atom = 1;
    }
}

}

float Str2Float (string x)
{
    stringstream ss(x);
    float StringWeight;
    ss >> StringWeight;
    return StringWeight;
}

float CalculateMoleculeWeight(Element ElmAry[30], Formula FormAry[30])
{
int i;
int j=0;
float MoleWT = 0;
float MoleSum = 0;
char e1;
char e2;
char f1;
char f2;

    for(i = 0; i < 30; i++)
    {
        f1 = FormAry[j].Element1;
        f2 = FormAry[j].ElementA;
        e1 = ElmAry[i].eN1;
        e2 = ElmAry[i].eN1;
        if
            (e1 == f1 && e2 == f2)
    {
        MoleWT = ElmAry[i].Weight * FormAry[j].Atom;
        MoleSum = MoleSum + MoleWT;
        j++;
    }
}
return MoleSum;
}

当我到达

 while(inputFile1)
 {
    Name = String1.substr(0,2);
    ElmAry[i].Name = Name;

    Weight = String1.substr(3,10);//invalid string position
    String1.clear();
    StringWeight = Str2Float(Weight);
    ElmAry[i].Weight = StringWeight;
    i++;
}
i--;

权重 = String1.substr(3,10); 给了我一个无效的字符串位置

4

1 回答 1

4

std::out_of_range当您尝试访问已分配空间之外的内存(在 STL 容器中)时,这是一个例外。在这种特殊情况下,您正在访问std::string尚未分配的 a 区域:

Weight = String1.substr(3,10); // empty string or string.length() < 4 throws here

std::string::substr采用必须在 . 封装的数组范围内的索引参数std::string。如果字符串只有 2 个字符长,并且您尝试从第 4 个位置开始获取字符,您将看到std::out_of_range异常。length在进行此类操作之前,您应该检查一下。

此外,您正在声明您的数组:

Element ElmAry[30];
Formula FormAry[30];

但是您正在遍历整个文件(可能包含 30 多个元素)。因此,当 时i >= 30,您超出了界限(并且行为将是未定义的)。

您可以通过使用 来解决这个问题std::vector,这将允许动态调整数组的大小,或者另一个集合(例如std::liststd::deque)。

于 2013-10-01T19:26:22.157 回答