c++ out-of-Auswahl bei Speicher Fehler
Hier ist der code, den ich für eine Programmierung Zuordnung, die ich habe. Im immer diese Fehlermeldung wenn ich das Programm starte
"Unbehandelte Ausnahme bei 0x772BC41F in STRUCT2.EXE: Microsoft C++ - Ausnahme: std::out_of_range an Speicherposition 0x0043ED04." Wenn verstehe ich das richtig, der Fehler bedeutet, dass mein array überschritten hat, werden die zugeteilten Speicherplatz. ist das richtig? und wenn dies richtig ist, was mache ich falsch? Meine input-Datei hat weniger als 30 Elementen in es.
#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;
}
wenn ich
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--;
Gewicht = String1.substr(3,10); gibt mir eine ungültige Zeichenfolge position
- Heilige code-dump, Batman!
- Viel zu viel code. Legen Sie einige Mühe in und schmale Ihrem problem.
- Führen Sie es unter einem debugger. Finden Sie heraus, wo es AV ist. Fix it.
- In Ihrem zweiten Auszug des Codes, die Sie noch nicht initialisiert
String1
nichts, kein Wunder, es gibt Sie Fehler, es ist leer.
Du musst angemeldet sein, um einen Kommentar abzugeben.
std::out_of_range
ist eine Ausnahme, die Sie erhalten, wenn Sie versuchen, Zugriff auf Speicher außerhalb des Raumes haben Sie reserviert (in einem STL-container). In diesem speziellen Fall, werden Sie den Zugriff auf Bereiche einesstd::string
nicht zugeordnet:std::string::substr
nimmt index-Parameter, müssen sich innerhalb der Begrenzungen des Arrays, welche vonstd::string
. Wenn die Zeichenfolge nur 2 Zeichen lang ist, und Sie versuchen, den Zeichen ab der 4. position, sehen Sie diestd::out_of_range
Ausnahme. Sie sollten überprüfen, dielength
vor, das zu tun diese Art der Bedienung.Darüber hinaus erklären Sie sich mit arrays:
Aber Sie sind Durchlaufen eine ganze Datei (welche potentiell mehr als 30 Elemente). Also, wenn
i >= 30
Sie außerhalb der Grenzen liegen (und das Verhalten undefiniert).Können Sie festlegen, dass bei Verwendung
std::vector
, die es erlauben, das array dynamisch Größe, oder eine andere Zusammenstellung (z.B.std::list
,std::deque
).out_of_range
, wenn Sie gehen vorbei am Ende ist es nur aufruft, UB.std::string::substr(3, 10)
auf eine leere Zeichenfolge ist ein wahrscheinlicher Kandidat (zumal OP nicht sagen, dass dies ist, wo der Fehler passiert).substr
ist falsch zu.out_of_range
wird nur ausgelöst, wennpos
(das erste argument) größer ist als der string-Größe. Der Graf (zweites argument) ist einfach geklemmt, wenn(pos + count) > size()
. Also der erste Anrufsubstr(0, 2)
immer erfolgreich, sogar auf einen leeren string. Siehe dieser doc. Zu VS werfen im debug-Modus, Sie dürfen das tun, weil der Vorgang UB in den ersten Platz, aber das ist definitiv nicht Teil der C++ - Spezifikation.Name = String1.substr(0,2);
wird nicht dazu führen, ein problem auf eine leere Zeichenfolge, werde es behandeln, dass2
als maximum.