Okay so I keep getting this error when I try to run my code and can't figure out how to fix it.
(Unhandled exception at 0x75195608 in hw6.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0101F850.)\
I have included my source code below. Also the file that I am reading from is not long at all so I don’t think that’s the problem.
int main() {
//Initializes all of the variables, strings,boolean, and vectors
ifstream inFS;
int count = 1;
int i = 0;
int j = 0;
int location = 0;
char ch;
bool marker = 0;
string filename = "hw6-Fall2017.txt";
string list = "ABCDEFGHIJKEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
vector<int> locations;
vector<int> find_Locations;
vector<char> notFound;
vector<char> Found;
//Iterates through the file searching for each of the characters
while (count <= 62) {
inFS.open(filename);
if (!inFS.is_open()) {
cout << "Could not open the file: " << filename << endl;
return 1;
}
while (inFS.get(ch) && marker == 0) {
location++;
if (ch == list[i]) {
marker = 1;
}
}
inFS.close();
//Sets characters not found to have a location of 0
if (marker == 0) {
location = 0;
}
locations.push_back(location);
marker = 0;
location = 0;
i++;
count++;
}
//Creates a table printing out the characters and their susequent locations
for (i = 0;i < list.size();i++) {
if (locations.at(i) == 0) {
cout << list[i] << " " << setw(6) << "NotFnd"<< " ";
notFound.push_back(list[i]);
}
else {
cout << list[i] << " " << setw(6) << locations.at(i) << " ";
find_Locations.push_back(locations.at(i));
}
j++;
if (j == 5) {
cout << endl;
j = 0;
}
}
cout << endl << endl << endl;
//Sorts the characters in the order that they were found
sort(find_Locations.begin(), find_Locations.end());
for (i = 0;i < find_Locations.size();i++) {
for (j = 0;j < locations.size();j++) {
if (find_Locations.at(i) == locations.at(j) && marker == 0) {
Found.push_back(list[j]);
j = locations.size();
}
}
}
count = 0;
j = 0;
//Creates a table printing out the characters in the oreder they were found
//in the text file along with their locations. Characters not found are
//displayed first with a location of "NotFnd".
for (i = 0;i < (Found.size() + notFound.size());i++) {
if (i < Found.size()) {
cout << Found.at(i) << " " << setw(6) << find_Locations.at(i)<< " ";
}
else {
cout << notFound.at(j) << " " << setw(6) << "NotFnd" << " ";
j++;
}
count++;
if (count == 5) {
cout << endl;
count = 0;
}
}
system("pause");
return 0;
}
The answer is not easy to find with code review.
But this line looks nice in itself
string list = "ABCDEFGHIJKEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
but together with this
while (count <= 62) {
It looks suspicious, I think it should have been
while (count < list.size()) { // 2*26+10==62
An "Off by one error" which could cause a problem here
for (i = 0;i < find_Locations.size();i++) {
for (j = 0;j < locations.size();j++) {
if (find_Locations.at(i) == locations.at(j) && marker == 0) {
Found.push_back(list[j]); // <--- if J>=list.size()
j = locations.size();
}
}
}
And a potential crash at the marked line.
But the real error is here
Found.push_back(list[j]); // j should have been i
Which should cause a crash at
cout << Found.at(i) << " " << setw(6) << find_Locations.at(i)<< " ";
Related
In my program for sorting an array of strings, I always get a position of 10 when binary searching a name. Why does this occur?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int MAXNAMES = 20;
void readArray(string names[])
{
ifstream inFile("names.txt");
string line;
int counter = 0;
if (!inFile.is_open())
{
cout << endl << "Cannot locate file names.txt" << endl;
exit(0);
}
else
{
cout << "Succesfully opened \"names.txt\" file." << endl;
}
while (getline(inFile, line))
{
names[counter++] = line;
}
inFile.close();
}
void displayArray(string names[])
{
for (int i = 0; i < MAXNAMES; i++)
{
cout << names[i] << endl;
}
cout << endl;
}
void selectionSort(string names[])
{
int i, j, minIndex;
string minString;
for (i = 0; i < MAXNAMES - 1; i++)
{
minIndex = i;
minString = names[i];
for (j = i + 1; j < MAXNAMES; j++)
{
if (minString.compare(names[j]) > 0)
{
minString = names[j];
minIndex = j;
}
}
if (minIndex != i)
{
string temp = names[i];
names[i] = names[minIndex];
names[minIndex] = temp;
}
}
}
void sequentialSearch(string names[], string name)
{
bool found = false;
int index = 0;
for (int i = 0; i < MAXNAMES; i++)
{
if (name.compare(names[i]) == 0)
{
found = true;
index = i;
break;
}
}
if (!found)
cout << "The name is not found." << endl;
else
cout << endl << "The name is found at index: " << index + 1 << "." << endl;
}
void bubbleSort(string names[])
{
string temp;
for (int j = 0; j < MAXNAMES - 1; j++)
{
for (int i = j + 1; i < MAXNAMES; i++)
{
if (names[j].compare(names[i]) > 0)
{
temp = names[j];
names[j] = names[i];
names[i] = temp;
}
}
}
}
int binarySearch(string names[], string name)
{
int l = 0;
int r = MAXNAMES - 1;
while (l <= r)
{
int m = l + (r - l) / 2;
int res = 0;
if (name == names[m])
res = 0;
if (res == 0)
return m;
if (name > (names[m]))
l = m + 1;
else
r = m - 1;
}
return -1;
}
int main()
{
string names[MAXNAMES];
readArray(names);
cout << "Array before sort:" << endl << endl;
displayArray(names);
cout << "Array after selection sort is:" << endl << endl;
selectionSort(names);
displayArray(names);
string nameToSearch;
cout << "Enter a name to (sequential) search for: ";
std::getline(std::cin, nameToSearch);
sequentialSearch(names, nameToSearch);
string choice;
cout << endl << "Replace first element of the array \"" << names[0] << "\" with \"" << nameToSearch << "\" Yes or No: ";
std::getline(std::cin, choice);
if (choice.compare("Yes") == 0 || choice.compare("yes") == 0)
{
names[0] = nameToSearch;
}
bubbleSort(names);
cout << endl << "Array after Bubble Sort is:" << endl;
displayArray(names);
cout << "Enter a name to (binary) search for: ";
std::getline(std::cin, nameToSearch);
int index = binarySearch(names, nameToSearch);
if (index == -1)
cout << endl << "The name is not found." << endl;
else
cout << endl << "The name is found at position " << (index + 1) << endl;
return 0;
}
Here is the input file used for the code:
names.txt
Collins, Bill
Smith, Bart
Allen, Jim
Griffin, Jim
Stamey, Marty
Rose, Geri
Taylor, Terri
Johnson, Jill
Allison, Jeff
Looney, Joe
Wolfe, Bill
James, Jean
Weaver, Jim
Pore, Rob
Rutherford, Rose
Javens, Renee
Harison, Rose
Setzer, Cathy
Pike, Gordon
Holland, Beth
In binarySearch, you have this sequence:
int res = 0;
if (name == names[m])
res = 0;
if (res == 0)
return m;
Since res will always be zero when that 2nd if is reached, it will always return on the first time thru the loop.
You can remove res completely, and just replace all that with
if (name == names[m])
return m;
I am using for loops combined with if statements to read integers from a text file into a two-dimensional array.
This is my code:
for (int i = 0; i < MAX_ROWS;i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
if (invalidnum = true) {
cout << *(*(ArrB + i) + j) << " ";
cout << "There is/are negative number(s) or zero(s) in the array imported from your text file." << endl;
}
}
}
This code will read in the first 6 integers (max_row * max_column) from a text file into ArrB.
If -1 exists in the first 6 integers, it will exit the loop and print out "The array does not have enough integers".
If there is no -1 in the first 6 integers, then it will check all 6 integers to see if there are any other negative numbers or zero.
If there are negative numbers or zero, I want it to still print out the array, then print out the error message (There is/are negative number(s) or zero(s) in the array imported from your text file) ONLY ONCE.
For example, this is my text file. As you can see, there is no -1 in the first 6 numbers, but there is a -7.
So, ideally, the result should be something like:
2 4 5 6 9 -7
There is/are negative number(s) or zero(s) in the array imported from your text file
But this is what I am getting if I run my code above:
-------------------------------------UPDATE--------------------------------------
Figured it out based on #ZedLepplin 's comment
Here is the code:
for (int i = 0; i < MAX_ROWS;i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
cout << *(*(ArrB + i) + j) << " ";
}
}
if (invalidnum == true) {
cout << "There is/are negative number(s) or zero(s) in the array imported from your text file." << endl;
}
You could just set a counter, and put the message outside of the loop.
Something like :
int counter = 0;
for(int i = 0; i < MAX_ROWS ; i++) {
if(myVector[i] == -1) {
counter++;
}
else {
// Do normal stuff
}
}
if(counter > 0) {
cout << "The array contained " << counter << "negative values" << endl;
}
Ho, and I'd advise to avoid comparisons to "true". If myVar is a boolean alrady, I can just do if(myVar). No need to do if(myVar == true).
And doing if(myVar = true) is worse, as it sets myVar to true, regardless of its initial value. That's a common typo that can be hard to detect when proofreading code.
Edited version (to adapt to comments) :
bool earlyNegativeOneFound = false;
int otherNegativeCounter;
for(int i = 0; i < MAX_ROWS ; i++) {
if(i < 6 && myVector[i] == -1) {
earlyNegativeOneFound = true;
break;
}
else if(myVector[i] < 0) {
cout << myVector[i] << endl;
otherNegativeCounter++;
}
else {
// Do normal stuff
}
}
if(!earlyNegativeOneFound && otherNegativeCounter> 0) {
cout << "The array contained " << otherNegativeCounter << "negative values" << endl;
}
Put the conditional error message print after your for loop. Leave the cout for displaying the array number inside the for loop so it is output for every iteration of the loop.
for (int i = 0; i<MAX_ROWS;i++) {
for (int j = 0; j<MAX_COLUMNS; j++) {
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
cout << * (*(ArrB + i) + j) << " ";
}
}
if (invalidnum = true) {
cout << "There is/are negative number(s) or zero(s) in the array imported from your text file." << endl;
}
I am not sure if this is what you meant
for (int i = 0; i < MAX_ROWS;i++) {
for (int j = 0; j < MAX_COLUMNS; j++) {
flag log = false;
inFile >> ArrB[i][j];
if (ArrB[i][j] == -1) {
bad = true;
cout << "The array does not have enough integers" << endl;
break;
}
else {
if (ArrB[i][j] < 1) {
invalidnum = true;
}
}
if (invalidnum = true) {
cout << *(*(ArrB + i) + j) << " ";
if(!flag)
{
cout << "There is/are negative number(s) or zero(s) in the array
imported from your text file." << endl;
flag = true;
}
}
}
}
Adding the flag boolean variable would allow the statement "there are negative numbers.." to be printed once.
Just store the message and print it where and when you want. Some psuedo-code:
std::string message;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j< M; ++j)
{
if (smth)
{
message {"Your message"};
break; // note that after break,
// you are still in the outer loop
}
else if (smth else)
{
message {"Your message"};
}
}
// print it here
}
// or here, or wherever you want to
ifstream myfile;
myfile.open("config.txt");
if (myfile.fail())
{
cerr << "Error opening config file" << endl;
myfile.close();
}
int line_no = 0;
while (line_no != 3 && getline(myfile, line3)) {
++line_no;
}
while (line_no != 7 && getline(myfile, line7)) {
++line_no;
}
while (line_no != 10 && getline(myfile, line10)) {
++line_no;
}
while (line_no != 14 && getline(myfile, line14)) {
++line_no;
}
while (line_no != 18 && getline(myfile, line18)) {
++line_no;
}
cout << line3 << endl;
cout << line7 << endl;
cout << line10 << endl;
cout << line14 << endl;
cout << line18 << endl;
gridXIdxA = stoi(ExtractString(line3, "=", "-"));
gridXIdxB = stoi(ExtractString(line3, "-", "\n"));
gridYIdxA = stoi(ExtractString(line7, "=", "-"));
gridYIdxB = stoi(ExtractString(line7, "-", "\n"));
cout << gridXIdxA << endl;
cout << gridXIdxB << endl;
cout << gridYIdxA << endl;
cout << gridYIdxB << endl;
int y = gridYIdxB + 1;
y > -1;
mapBoundaryX = gridXIdxB + 6; // dynamic array to print out boundary of city map
mapBoundaryY = gridYIdxB + 4;
int** dMapBoundaryArray;
dMapBoundaryArray = new int*[mapBoundaryX]();
for (int i = 0; i < mapBoundaryX; i++)
{
dMapBoundaryArray[i] = new int[mapBoundaryY];
}
for (int i = 0; i < mapBoundaryX; i++)
{
cout << endl;
for (int j = 0; j < mapBoundaryY; j++)
{
dMapBoundaryArray[i][j] = i;
if (i == 0 && j > 0 && j < gridXIdxB+4)
{
cout << "# "; // top
}
if (i == 0 && j == 0)
{
cout << " ";
}
if (i == (gridYIdxB+2) && j > 0 && j < gridXIdxB+4)
{
cout << "# "; // bottom
}
if (i == (gridYIdxB + 2) && j == 0)
{
cout << " ";
}
if (i>0 && i<12 && j==1)
{
cout << "#"; // left
}
else if (i == 6 && j == 3)
{
cout << " ";
cout << 3;
}
else if (i == 6 && j == 4)
{
cout << " ";
cout << 3;
}
else if (i == 7 && j == 4)
{
cout << " ";
cout << 3;
}
else if (i > 0 && i < 12 && j == 13) //right
{
cout << setw(24)<<right << "#";
}
if (i == 13 && j > -1 && j < 2) //x axis
{
cout << " ";
}
if (i == 13 && j > 1 && j < 13)
{
x = x++;
cout <<" " << x; //x axis
}
if (j == 0 && i <= gridYIdxB+1 && i >= 1) // y axis
{
y = --y;
cout << y; //y axis
}
}
}
Hi, have some questions that i need help with, beginner to c++ currently so definitely appreciate if stuff can be explained in simple terms. I can manage to create the edges of the coordinate map but I also need to pinpoint certain coordinates within the map and mark them for eg. with a '3'. Is there anyway to pinpoint the coords without moving the column of '#' on the right?
Output
before marking coords
after marking coords
You may already have noticed that C++ alone has no facilities to set a character at a certain position on the screen. curses is a rather wide-spread library that helps with that. However, if you want to stay with your own code you can still get some inspiration from how curses handles output. The contents of the screen are buffered in memory and only when you request it all of it is updated. You can do similar in your own code. Store the contents you want to print on the screen in a std::vector<std::vector<char> or a std::vector<std::string>. Modify the contents as desired and when printing you do not have to bother about alignment and formatting anymore, it is just a simple loop:
for (const auto& line : screen) {
for (const auto& character : line) std::cout << character;
std::cout << "\n";
}
I am having a problem with incrementing a single item in an array. It ends up incrementing another array.. How does it do this? this is what I have:
string simulateFIFO(darray<int> requests, int frameSize) {
string results;
int currentPages[frameSize];
int timer[frameSize];
int hits = 0;
int faults = 0;
cout << "STARTING FIFO" << endl;
for (int i = 0; i < requests.size(); i++) {
cout << requests[i] << " ";
}
cout << endl;
cout << endl;
for (int i = 0; i < frameSize; i++) {
currentPages[i] = -1;
timer[i] = 0;
}
// Start Calculations
for (int i = 0; i < requests.size(); i++) {
bool requestSet = false;
for (int j = 0; j < frameSize; j++) {
if (currentPages[j] < 0) {
// Current frame does not have a page
cout << "FRAME IS EMPTY" << endl;
currentPages[j] = requests[i];
requestSet = true;
faults++;
j = frameSize;
}
else if (currentPages[j] == requests[i]) {
cout << "FRAME IS SAME AS REQUEST" << endl;
// Current Frame is set the the page being requested
timer[j] = 0;
requestSet = true;
hits++;
j = frameSize;
}
cout << currentPages[j] << endl;
timer[j]++;
cout << currentPages[j] << endl;
}
// Check to see if a request was set or not
if (requestSet == false) {
cout << "FRAME NEEDS REPLACED" << endl;
// The request wasnt set. Determine which frame to replace with the new request
int lastUsed = 0;
int lastUsedIndex = 0;
for (int j = 0; j < frameSize; j++) {
if (timer[j] > lastUsed) {
lastUsed = timer[j];
lastUsedIndex = j;
}
}
currentPages[lastUsedIndex] = requests[i];
//timer[lastUsedIndex] = 0;
faults++;
}
cout << "HEY 3: " << currentPages[0] << endl;
cout << "NEW FRAME: ";
for (int j = 0; j < frameSize; j++) {
cout << currentPages[j] << " ";
}
cout << endl;
cout << endl;
}
cout << "FIFO" << endl;
cout << faults << endl;
cout << hits << endl;
cout << endl;
return results;
}
My Output ends up being
0
1
Why does increasing one array actually increase the other as well?
Your code includes a possible path of execution:
j = frameSize;
followed by
timer[j]++;
This accesses out of bounds: for an array of dimension frameSize, the valid indices are 0 through frameSize-1.
I guess you actually want to exit the loop; if so then replace j = frameSize; with break; .
NB. int timer[frameSize]; is not permitted in ISO C++; array bounds must be known at compile-time. Your code is relying on a compiler extension.
I'm programming Djikstra's algorithm in C++ and I'm getting the correct distances from the source node to the end node but i'm having trouble backtracking the previous nodes visited. It's giving me sort of the correct answer but not the correct answer. Also I noticed with different input data of 1 as the start node and 16 as the finish node that my algorithm is using path's that aren't allowed (it goes from 1 -> 10 -> 8 when 8 isn't allowed) but that could just be me getting path backtracking wrong.
http://pastebin.ca/3188762 - Input data (1st = max nodes and then nodes(node num, x,y) then max edges then all edges with the last line being the start and finish node)
http://textuploader.com/awp89 - Output in console
Code:
#include<iostream>
#include<fstream>
using namespace std;
struct Node
{
int nodeNum;
double x, y;
};
void dji(double map[50][50],int startNode,int endNode,int maxNodes);
int main()
{
int tempA, tempB, maxNodes, maxEdges, startNode, endNode;
double tempD;
double map[50][50];
ifstream fin;
fin.open("ass03.txt");
if(fin.good())
{
fin >> maxNodes;
Node allNodes[maxNodes];
for(int i = 0; i < maxNodes; i++)
{
for(int k = 0; k < maxNodes; k++)
{
map[i][k] = -1;
}
map[i][i] = 0;
}
for(int i = 0; i < maxNodes; i++)
{
fin >> allNodes[i].nodeNum >> allNodes[i].x >> allNodes[i].y;
}
fin >> maxEdges;
for(int i = 0; i < maxEdges; i++)
{
fin >> tempA >> tempB >> tempD;
map[tempA-1][tempB-1] = tempD;
map[tempB-1][tempA-1] = tempD;
}
fin >> startNode >> endNode;
cout << "\t";
for(int i = 0; i < maxNodes; i++)
{
cout << i+1 << "\t";
}
cout << endl;
for(int i = 0; i < maxNodes; i++)
{
cout << i+1 << "\t";
for(int k = 0; k < maxNodes; k++)
{
cout << map[i][k] << "\t";
}
cout << endl;
}
dji(map, startNode-1, endNode-1, maxNodes);
}
else
{
cout << "Incorrect filename" << endl;
}
return 0;
}
void dji(double map[50][50], int startNode,int endNode,int maxNodes)
{
int Intersections[maxNodes], path[maxNodes], temp; // equate for actual endNode
double Distances[maxNodes];
for(int a = 0; a < maxNodes; a++)
{
Intersections[a] = a;
Distances[a] = map[startNode][a];
if(map[startNode][a] != -1)
{
path[a] = startNode;
}
else
{
path[a] = -1;
}
}
Intersections[startNode] = -1;
Distances[startNode] = 0;
double minValue = 99999;
int minNode = 0;
for(int l = 0; l < maxNodes; l++)//loop max amount of times to avoid having to function loop (disconsider l = startNode)?
{
for (int i = 0; i < maxNodes; i++)
{
if(Intersections[i] == -1)
{
continue;
}
if(Distances[i] > 0 && Distances[i] < minValue)
{
minValue = Distances[i];
minNode = i;
}
}
if(Intersections[minNode] == endNode)
{
temp = l;
}
Intersections[minNode] = -1;
cout << " --- Used Node - " << minNode+1 << endl;
for(int i = 0; i < maxNodes; i++)
{
cout << Intersections[i] << " ";
}
cout << endl;
for(int i = 0; i < maxNodes; i++)
{
if(map[minNode][i] < 0)
{
continue;
}
if(Distances[i] < 0)
{
Distances[i] = minValue + map[minNode][i];
path[i] = minNode;
continue;
}
if((Distances[minNode] + map[minNode][i]) < Distances[i])
{
Distances[i] = minValue + map[minNode][i];
path[i] = minNode;
}
}
minValue = 99999;
}
for(int i = 0; i < maxNodes; i++)
{
cout << "Node:" << i+1 << " - PATH= " << path[i] << " distance = " << Distances[i] << endl;
}
cout << "Additional nodes used: " << temp << endl;
temp = path[endNode];
for(int i = 0; i < 4; i++)
{
cout << temp << " ";
temp = path[temp];
}
/*temp = path[endNode];
int temp2 = path[endNode];
for(int i = 0; i < maxNodes; i++)
{
if(i == 0)
{
cout << endNode << " ";
cout << temp << " ";
}
if(i%2 == 0)
{
if(temp != endNode)
{
temp = path[temp2];
cout << temp << " ";
}
else
{
cout << temp << " ";
i = maxNodes;
}
}
else
{
if(temp2 != endNode)
{
temp2 = path[temp]-1;
cout << temp2 << " ";
}
else
{
cout << temp2 << " ";
i = maxNodes;
}
}
}*/
//cout << "PATH = " << endNode << " < - " << path[endNode] << " < - " << path[path[endNode]-1] << " < - " << path[path[path[endNode]-1]-1] << endl;
//cout << "TEST" << path[4] << " " << path[8] << " " << path[16] << " " << endl;
}
Thank you for any help
The problem is you're mixing zero-based and one-based indexing. Your vertices are numbered 1-20, and those are the numbers that end up in your path array with valid indices 0-19. You then use the vertex number as the index into the array.
Change your code to either consistently use the vertex number, or consistently use the array index.