C++ Lines not executing after a for loop. Loop not infinite - c++

Most of the answers I'm coming across boil down to in infinite loop, but I've inserted some cout statements for diagnostic purposes and I'm thoroughly convinced this is not the case- it looks like the nested for loop finishes but simply skips over some lines before returning to the top of the outside for loop. The only time something gets pushed back is on the first iteration when the for nested loop is skipped completely. As is, the debugger gives an out of range vector fault, I assume because new unique items aren't being pushed back. Any ideas how to get around this?
Template <class T>
void count_unique(string filename, vector<T> input) {
vector<T> unique;
vector<int> count;
bool found = false;
ifstream fin;
fin.open(filename);
T line;
while (!fin.eof()) {
fin >> line;
input.push_back(line);
}
fin.close();
cout << input.size() << endl;
for (unsigned int i = 0; i < input.size(); i++) {
cout << input.at(i) << endl;
}
for (unsigned int i = 0; i < input.size(); i++) {
cout << input.at(i) << endl;
found = false;
for (unsigned int j = 0; j < unique.size(); i++) {
cout << unique.at(j) << "\t=\t" << input.at(i) << " ->" << unique.size() << endl;
if (input.at(i) == unique.at(j)) {
count.at(j)++;
found = true;
cout << "Incremented" << endl;
}
else {
cout << "None;" << endl;
}
}
cout << "Found=" << found << endl;
if (!found) {
unique.push_back(input.at(i));
count.push_back(1);
found = false;
cout << "Pushed back" << endl;
cout << "#";
for (unsigned int i = 0; i < unique.size(); i++) {
cout << unique.at(i) << "\t-\t" << count.at(i) << endl;
}
cout << "#" << endl;
}
}
for (unsigned int i = 0; i < unique.size(); i++) {
cout << "\t" << unique.at(i) << "\t=\t" << count.at(i) << endl;
}
}

Your inner loop incremements the wrong variable. It is actually an infinite loop, since j will never change. This is also why you get the out of range, i will continuously increase, beyond the size of input
//...
for (unsigned int i = 0; i < input.size(); i++) {
cout << input.at(i) << endl;
found = false;
for (unsigned int j = 0; j < unique.size(); j++) { // HERE

Related

How to print a message one time after all the iterations in the loop "for" are done?

My program analyzes the array in the loop "for". If all elements satisfy the condition, it should print a message one time, but my program does it after each iteration.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
const int size = 32;
int ARR[size];
cout << "The size of the set is " << size << " elements." << endl << endl;
cout << "Enter the elements of the set: ";
for (int i = 0; i < size; i++)
{
cin >> ARR[i];
}
for (int i = 0; i < size; i++)
{
if (ARR[i] > ARR[i])
cout << "\nThe relation is reflexive." << endl;
else
cout << "\nThe relation is not reflexive." << endl;
}
return 0;
}
I need that message to be printed after all the iterations are done. How can I achieve that result?
It's pretty easy, just use a boolean flag to determine if the condition is met:
bool isReflexive = true;
for (int i = 0; i < size; i++) {
if (ARR[i] <= ARR[i]) {
isReflexive = false;
break;
}
}
if(isReflexive)
cout << "\nThe relation is reflexive." << endl;
else
cout << "\nThe relation is not reflexive." << endl;
Note: The code above will always set isReflexive to false. You also need to compare two different indices:
for (int i = 1; i < size; i++) {
if (ARR[i-1] <= ARR[i]) { // Or whatever the correct comparison is
isReflexive = false;
break;
}
}
I would suggest to separate analysis of "reflexiveness" from printing the result. That would allow you to simply end the loop as soon as negative result is determined:
#include <iostream>
using namespace std;
bool IsReflexive(int a[], int size)
{
for (int i = 0; i < size; i++)
{
if (a[i] > a[i]) // TODO: correct this!!!
return false;
}
return true;
}
int main()
{
const int size = 32;
int ARR[size];
cout << "The size of the set is " << size << " elements." << endl << endl;
cout << "Enter the elements of the set: ";
for (int i = 0; i < size; i++)
{
cin >> ARR[i];
}
if (IsReflexive(ARR, size))
cout << "\nThe relation is reflexive." << endl;
else
cout << "\nThe relation is not reflexive." << endl;
return 0;
}

Option to print output to screen or given file name (c++)

I would like option 2 to pass the output to a typed file name. However, the program is creating the file but not passing the output to the file. I think just using ostream is fine here, but don't know how to go about it.
void displayTable(int n, char op) {
int printOption;
string outputFileName;
ofstream createOutputFile;
while (true) { //option for print screen or print to file
cout << "Select: \n1) Print on Screen \n2) Print to a file name \nSelection: ";
cin >> printOption;
if (printOption == 1)
break;
else if (printOption == 2){
cout << "Type in the name for the output file." << endl;
cin >> outputFileName;
createOutputFile.open(outputFileName);
break;
}
else
cout << "Please enter a valid number." << endl;
}
int max = getMaxSize(n, op);
cout << setw(max) << op << "|";
for (int i = 1; i <= n; ++i) {
cout << setw(max) << i;
}
cout << endl;
for (int i = 0; i < max; ++i) {
cout << "-";
}
cout << "+";
for (int i = 0; i < n * max; ++i) {
cout << "-";
}
cout << endl;
for (int i = 1; i <= n; ++i) {
cout << setw(max) << i << "|";
for (int j = 1; j <= n; ++j) {
cout << setw(max) << getValue(i, j, op);
}
cout << endl;
}
cout << endl;
createOutputFile.close();
}
You are not printing anything to createOutputFile, everything is being printed to cout instead. That is why to don't see anything in the file, and everything in the console.
The easiest way to solve your issue is to redirect cout to createOutputFile's output buffer, eg:
auto cout_buff = cout.rdbuf();
...
createOutputFile.open(outputFileName);
cout.rdbuf(createOutputFile.rdbuf())
// all cout outputs will now go to the file...
...
cout.rdbuf(cout_buff); // restore when finished...
Otherwise, move your print logic to a separate function that takes an ostream& as a parameter:
void doMyLogic(ostream &os)
{
// print to os as needed...
}
...
if (printOption == 1) {
doMyLogic(cout);
break;
}
if (printOption == 2) {
...
ofstream createOutputFile(outputFileName);
doMyLogic(createOutputFile);
break;
}
...

C++ Out of Range Error

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)<< " ";

Why does incrementing one array, increment another?

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.

How can I let users to input values into the sudoku board?

I'm having trouble generating and inserting numbers inside the Board. Here is what I have so far:
enter code here
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
bool Valid_Set(int line[])
{
bool found = true;
for (int t = 1; (t <= 9 && found); ++t)
{
found = false;
for (int i = 0; i < 9; ++i)
if (line[i] == t) found = true;
}
return found; // returns true if all value 1-9 are in array.
}
bool Valid_Matrix(int sud[9][9])
{
int i, j, check[9];
bool valid = true;
// check each row
for (j = 0; (j < 9) && valid; ++j)
{
for (i = 0; i < 9; ++i)
check[i] = sud[i][j];
valid = Valid_Set(check);
}
// check each column
for (j = 0; (j < 9) && valid; ++j)
{
for (i = 0; i < 9; ++i)
check[i] = sud[j][i];
valid = Valid_Set(check);
}
// check 3x3 area
for (i = 0; (i < 9) && valid; i += 3)
{
for (j = 0; (j < 9) && valid; j += 3)
{
int t = 0;
for (int x = 0; x < 3; ++x)
for (int y = 0; y < 3; ++y)
check[t++] = sud[x + i][y + j];
valid = Valid_Set(check);
}
}
return valid;
}
void numGenerator(int A[]){
for (int i=0; i<9; i++){
A[i]=(1+rand()%9);
}
}
bool check_for_validity(int A[]){
int counter=0;
while (counter!=9){
numGenerator(A);
counter++;
}
for (int i=0; i<9; i++)
for (int j=0; j<9; j++){
if(A[j]==A[i])
numGenerator(A);
}
return true;
}
void main (){
//Descriptions and genral ideas
cout << "WELCOME TO SUDOKU " << endl;
cout << endl;
cout << "RULES: "<< endl;
cout << endl;
cout << "->You'll be given a 9x9 board with some numbers depending on which level of difficulty you choose to play."<< endl;
cout << endl;
cout << "->You have to arrange numbers from 1 to 9 so that a number shows up once in one row, one column and in a 3x3 box." << endl;
cout << endl;
cout << "So, let's get started" << endl;
cout << endl;
cout <<endl;
char dash[9][9];
for (int array=0; array<9; array++) {
for (int array2=0; array2<9; array2++) {
dash[array][array2]='_';
}
}
char row[9];
char column[9];
int num[81];
int num2[9][9];
int length;
length=strlen(row);
//Replaces the _'s in the specified rows/columns and replaces them with the integer the user specified.
for (int i=0; i<length; i++) {
dash[row[i]][column[i]]=num[i]+'0';
}
//Builds the Sudoko board and outputs the full 9x9 array.
cout << " 0 1 2 3 4 5 6 7 8 " << endl;
cout << "-----------------------------------------" << endl;
int i=0;
for (int count=0; count<3; count++) {
for (int count2=0; count2<3; count2++) {
cout << "||_" << dash[count][count2*3] << "_|_" << dash[count][count2*3+1] << "_|_" << dash[count][count2*3+2] << "_";
}
cout << "||" << i << endl;
i++;
}
cout << "-----------------------------------------" << endl;
int j=3;
for (int count=3; count<6; count++) {
for (int count2=0; count2<3; count2++) {
cout << "||_" << dash[count][count2*3] << "_|_" << dash[count][count2*3+1] << "_|_" << dash[count][count2*3+2] << "_";
}
cout << "||" << j << endl;
j++;
}
cout <<"-----------------------------------------" << endl;
int z=6;
for (int count=6; count<9; count++) {
for (int count2=0; count2<3; count2++) {
cout << "||_" << dash[count][count2*3] << "_|_" << dash[count][count2*3+1] << "_|_" << dash[count][count2*3+2] << "_";
}
cout << "||" << z << endl;
z++;
}
cout << "-----------------------------------------" << endl;
for (int row = 0; row < 9; row++) {
cout << "Enter values for row " << row + 1 << " : ";
for (int col = 0; col < 9; col++)
cin >> dash[row][col];
cout << endl << endl;
}
system("pause");
}
This whole section is wrong
char row[9];
char column[9];
int num[81];
int num2[9][9];
int length;
length=strlen(row);
//Replaces the _'s in the specified rows/columns and replaces them with the integer the user specified.
for (int i=0; i<length; i++) {
dash[row[i]][column[i]]=num[i]+'0';
}
You are using row and column even though they haven't got any values. Most likely this will crash your program.
Hard to know what you expected this to do. Perhaps you could explain?
Here's a suggestion for inputing values. Maybe you'll find it useful
// get the user's values
int row, column, value;
cout << "Enter a row number, column number, and value. All numbers should be between 1 and 9\n";
cin >> row >> column >> value;
// put the value in the board, add '0' to convert the integer to a digit
dash[row][column] = value + '0';