I have a text file below that I read from.

0123456789012345678
       IN    NUMBER
LOOP   LD    NUMBER
       BZ    LPEND
       LD    TOTAL
       ADD   ONE
       STO   TOTAL
       LD    ZERO
       SUB   NUMBER
       BGTR  ENDIF
       BZ    ENDIF
       LD    POSITS
       ADD   ONE
       STO   POSITS
ENDIF  IN    NUMBER
       B     LOOP
LPEND  LD    POSITS
       MPY   HNDRD
       DIV   TOTAL
       STO   PRCNT
       OUT   PRCNT
       STOP
NUMBER DC    0
TOTAL  DC    0
ONE    DC    1
POSITS DC    0
HNDRD  DC    100
PRCNT  DC    0
ZERO   DC    0
       END

I have already read in the third column and put that into an array. In the second part of my program I'm get the last column using substr(13,6) because it starts at position 13 and goes 6 positions. I then compare that string to what I have in my array of that same column. If i try to use that substring in a while loop I get this error "libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string Abort trap: 6". If I put the substr outside of the while loop it'll work, but I only get the first substr. When I do a string.length on the strings that I have in the array they are different lengths. 1)I didn't know that when I stored them in an array it would remove spaces and 2)I think that's why I'm getting out of range. So how do i get this to work. I'll paste my code below.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

void getSymbolTable();
void symbolOut();
void getInstructDirective();


int const CODESIZE = 100; //constant variable for the array size

string symLabel[CODESIZE];//array to hold symbols
int symAddress[CODESIZE];//array to hold the address of the array
int memory[CODESIZE]; //holds value from label added to value from operand
int symSize = 0;
int pc = 0;
string opCode; //holds each line of code
string label; //temporary hold for symbol
string instructions; //temporary hold of instructions

string instruct[] = {"STOP", "LD  ", "STO ", "ADD ", "SUB ", "MPY ", "DIV ", "IN  ",
                     "OUT ", "B   ", "BGTR", "BZ  "}; //hard coded instructions



ifstream inFile;

int main()
{

    getSymbolTable();

    symbolOut();

    getInstructDirective();

return 0;
}


void getSymbolTable()
{
    inFile.open("simprog.txt"); //open file
    getline (inFile, opCode);

    instructions = opCode.substr(7,4); //copy the operation code portion of the current line

    while (instructions != "END")
        {
          if (opCode.substr(0,6) != "      "){  // test the first column to see if there is a symbol
                symLabel[symSize].append(opCode,0,6);  // adds the label to the array
                symAddress[symSize] = pc;   //stores the address in a parallel array
                symSize++; //keeps track of the number of total number of lines in simcode
                }

        pc++;  //increment the program counter
        getline (inFile,opCode); //reads the next line of the file

        instructions = opCode.substr(7,4);  //copy the operation code portion of the current line

        }
        inFile.close();

}


void symbolOut()
{
   for ( int i = 0; i < symSize; i++){
    cout << symLabel[i] << "  " << symAddress[i] << endl;
    }
}


void getInstructDirective()
{
    inFile.open("simprog.txt"); //open file
    string temp; //hold variable that corresponds to dc for conversion to int
    string operand; //temporary holds operand

    pc = 0;// reset the program counter so the program can be translated into machine language
    getline(inFile,opCode);//read the first line of the program
    instructions = opCode.substr(7,4); // put the instruction of the current line to a string variable
    //operand = opCode.substr(13,6);


    while (instructions !="END"){ // read through the file until it sees the string "END"

    label = opCode.substr(0,6); //copy the operation code portion of the current line
    instructions = opCode.substr(7,4); // put the instruction of the current line to a string variable
    //operand = opCode.substr(13,6); **If I uncomment this I get an error**
    //cout << operand << endl;

    if (instructions == "STOP") // when the instructions reach "STOP" a 0 is put into memory array
        memory[pc] = 0;
    if (instructions == "DC  "){  // if the instruction sees "DC" it will put the associated variable integer into memory array
        temp = opCode.substr(13,6);

    memory[pc]= stoi(temp); //stoi converts a string to an int
    }

    for (int i = 0; i < 12; i++){
        if (instructions == instruct[i]) //compares what is currently in the instructions variable to the instruct array
        memory[pc] = (i * 100); // multiplies the instruction number by 100 and puts that number into the memory array

    }

    for (int i = 0; i < 10; i++){
        if(operand == symLabel[i]){
        memory[pc] += symAddress[i];
        }
    }

    pc++; // increments the programm counter
    getline(inFile,opCode); // read the next line of the file

    }
    inFile.close();

    for (int i = 0; i <= pc; i++)
    cout <<  i <<"  " << memory[i] << endl; // prints the subcript number and the memory array

}

Your problem is one or two things:

(a) the line STOP in your input only has 11 characters in it.
(b) You don't check the input size in your code before cutting.

If you put this in your code :

operand = (opCode.size()>12) ? opCode.substr(13,6) : "";

the code runs to completion.

Obviously, I would also do the same for the instructions = ... line above.

Edited 2 Years Ago by StuXYZ

I put the line above in and it works for the strings that are exactly 6 characters long, but still doesnt "see" the other ones. Like the loop, endif, lpend....

I added that check for instructions also, same output.
What exactly does that check do? If the string is greater than 12 charachters, then ?

When I do operand.size() this is the output I get

NUMBER  6
NUMBER  6
  6ND
  6AL
  4
  6AL
  5O
NUMBER  6
  6IF
  6IF
POSITS  6
  4
POSITS  6
NUMBER  6
  5P
POSITS  6
  6RD
  6AL
  6NT
  6NT
  0
  2
  2
  2
  2
  4
  2
  2
  0

If i take operand = (opCode.size()>12) ? opCode.substr(13,6) : ""; i get this output.

NUMBER  6
NUMBER  6
  6ND
  6AL
  4
  6AL
  5O
NUMBER  6
  6IF
  6IF
POSITS  6
  4
POSITS  6
NUMBER  6
  5P
POSITS  6
  6RD
  6AL
  6NT
  6NT
This question has already been answered. Start a new discussion instead.