C++ user input manipulation - c++

I am very new to C++ and appreciate all the help, so please be patient with me! I was tasked with writing a C++ program which essentially emulates a simple CPU.
My overall goal is to have the user input various 3 digit numbers into an array I have created called "memory". The array "memory" will have 100 available locations and the user is allowed to load their input into any available spots (the array is sized [100][2] because i want the last two digits to be treated as a single number).
The variable "programCounter" will represent the beginning location for where the user input will be stored within the array. So, for example, if the user inputs the value "20" for programCounter, then the user's input will be stored starting from the 21st location in the array and beyond, until their input is finished. What I have written below does not work and the loop for the user input into "memory" never ends. Is there another way to have the user input their values into the array, and then provide some sort of exit code to let the program know that the user is finished inputting?
Here is my code:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main (void)
{
string name;
char inputCardResponse;
ifstream inFile;
ofstream outFile;
int memory [100][2] = {001}; // sets the value of the first memory spot to "001"
int inputCard [16][2];
int outputCard [16][2];
int instructionRegister;
double accumulator;
int programCounter;
cout << "Hello! Welcome to Simple Computer Version 1.0.\nWhat is your name? \n";
getline(cin, name);
cout << "Thank you for using my Simple Comuter "<<name<<"!\n";
cout << "Let's get started!\n";
cout << "Below is the table of Opcodes and their functions:";
cout << endl << endl;
{
cout << setw(9) << "| Opcode" << setw(20) << setfill('-') << "Function" << setw(12) << "|" << endl;
cout << setw(9) << "| ------" << setw(20) << setfill(' ') << "-------" << setw(12) << "|" << endl;
cout << setw(5) << "| 0_ _" << setw(20) << setfill('-') << "Input" << setw(14) << "|" << endl;
cout << setw(5) << "| 1_ _" << setw(21) << setfill('-') << "Output" << setw(13) << "|" << endl;
cout << setw(5) << "| 2_ _" << setw(18) << setfill('-') << "Add" << setw(16) << "|" << endl;
cout << setw(5) << "| 3_ _" << setw(23) << setfill('-') << "Subtract" << setw(11) << "|" << endl;
cout << setw(5) << "| 4_ _" << setw(22) << setfill('-') << "Load AC" << setw(12) << "|" << endl;
cout << setw(5) << "| 5_ _" << setw(23) << setfill('-') << "Store AC" << setw(11) << "|" << endl;
cout << setw(5) << "| 6_ _" << setw(19) << setfill('-') << "Jump" << setw(15) << "|" << endl;
cout << setw(5) << "| 7_ _" << setw(22) << setfill('-') << "Test AC" << setw(12) << "|" << endl;
cout << setw(5) << "| 8_ _" << setw(23) << setfill('-') << "Shift AC" << setw(11) << "|" << endl;
cout << setw(5) << "| 9_ _" << setw(19) << setfill('-') << "Halt" << setw(15) << "|" << endl;
}
cout << endl << endl;
//Input section
cout << "Please plan your program out. This emulator requires the user to enter a starting value";
cout << "for the program counter (typically cell 20 is chosen)\n";
cout << "When you are ready, please enter the starting cell you have chosen for the program counter: ";
cin >> programCounter; // Initializes the program counter value
cout << "Now that you have chosen a starting cell, please start entering your program: \n";
// This loop stores the user's program into the array named "memory". What happens if input<100??
for(;programCounter < 100; programCounter++)
{
cin >> memory[programCounter][2];
}
cout << "Do you have any information to store in the input card?\n";
cout << "(Please input uppercase Y for Yes or N for No \n";
cin.get(inputCardResponse);
if(inputCardResponse == 'Y')
{
cout << "There are 15 input slots available. Please keep this in mind when inputting: \n";
for (int inputCounter=0; inputCounter < 15; inputCounter++)
{
cin >> inputCard[inputCounter][2];
}
}
else{
cout << "Most programs require inputs.\n";
cout << "Please come back when you are ready with a file!\n";
}
return 0;
}

C/C++ arrays are 0-indexed. So if you have array, your indexes will be from 0 to (array size-1)
int a[5]; //You initialized array of 5 integers. You can only access this elements: a[0], a[1], a[2], a[3], a[4]
You are accessing an element out of bounds.
In these lines:
cin >> memory[programCounter][2];
cin >> inputCard[inputCounter][2];
Change 2 to 0 or 1, so you don't access element which is out of bounds.
Also, you don't have any variable which represents you the limit of input. Your limit is 100 so if you input a small number it will require lot of input numbers from you, so maybe that's why you think it will never stop input (but it actually will when it reaches 100). You should make a variable which represents you a limit of input, so you don't have this:
for(;programCounter < 100; programCounter++)
{
cin >> memory[programCounter][2];
}
but this:
for(;programCounter < inputLimit; programCounter++)
{
cin >> memory[programCounter][2];
}
Hope this helps!

This answer will not solve your problem but will get you on the path. Also, this is a response to the following comment:
#crayzeewulf - the user will input a 3 digit number (such as 345). The first
digit "3" will represent an opcode and the remaining digits "45" will represent
either the value to be manipulated, or the location of a spot in the array
"memory". That's why I was thinking of making the array have 100 rows and 2
columns. Is there another way to accomplish this? Thank you!
I now see what you meant in your original question. However, assigning values to or reading values via the >> operator into variables does not work the way you might be expecting. When you declare an array like the following:
int memory[100][2] ;
you are allocating space for 200 integers that you can imagine being arranged in a table with 100 rows and 2 columns. The first row has index 0 and first column has index 0. The last row has an index 99 and last column has index 1:
+------------+------------+
| Column 0 | Column 1 |
+------------+------------+
Row 0 | | |
+------------+------------+
Row 1 | | |
+------------+------------+
...
+------------+------------+
Row 99 | | |
+------------+------------+
Each cell in this table may only store an int value. When you initialize memory[][] using a statement such as the following (I am using 123 instead of 001 for a reason, see more comments later):
int memory[100][2] = {123} ;
the program simply puts the integer 123 in column 0 of row 0:
+------------+------------+
| Column 0 | Column 1 |
+------------+------------+
Row 0 | 123 | 0 |
+------------+------------+
Row 1 | 0 | 0 |
+------------+------------+
...
+------------+------------+
Row 99 | 0 | 0 |
+------------+------------+
The compiler or resulting program has no way of knowing that the number needs to be split into 1 and 23. It does not put 1 in column 0 and 23 in column 1 of the first row, for example. You will have to figure out a way to do this yourselves.
Going back to your original code, it used a value of 001 to initialize the array:
int memory[100][2] = {001} ;
C++ treats integer literals that start with 0 very differently. A leading 0 in literals causes C/C++ compilers to treat them as octal values. So, be very careful when you write literals that have leading zeroes. For example 012 is not equal to 12 in C++.
Finally, if you try to put something in column 2 of this table you are asking for a lot of trouble. The table only contains columns 0 and 1. When you try to place values into the non-existing column 2, the values may end up at unexpected locations in the memory being used by your program. The behavior of the program is unpredictable in this case and will most likely be entirely different from what you expected.
As you are trying to learn C++, I would suggest you read about how arrays and variables work from one or more of the books listed here. Once you have a better handle on the basic concepts, a great way to learn more advanced and application-specific concepts is to look at existing code that does something similar. If you search for similar codes on Google or StackOverflow, you will find several ways of approaching this assignment. Carefully study the codes that you find, make sure you understand them, run them, tweak them if you can and see what happens, etc. Now that you are armed with this additional knowledge, write your own code from scratch. Hope that gets you the answer. I also highly recommend following the suggestions of this answer before you ask your question on SO. :) Cheers!

Related

Fundamentally misunderstanding alignment and setw?

I'm asking this after googling for 2 hours now. As the title says I think I'm misunderstanding how to use the two things above. I'm attempting to create two distinct columns that show output and are in line with one another. However it seems no matter what I do they won't line up.
My code is as follows
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
const double THEATHERCUT = .80;
const double DISTRIBUTORCUT = .20;
const int CHILDCOST = 6;
const int ADULTCOST = 10;
string movieName;
int childTickets, adultTickets, childGrossRevenue, adultGrossRevenue, totalGrossRevenue, distributorRevenue, totalNetRevenue;
//User Input
cout << "What movie was viewed?" << endl;
getline(cin, movieName);
cout << "How many adult tickets were sold?" << endl;
cin >> adultTickets;
cout << "How many child tickets were sold?" << endl;
cin >> childTickets;
// Maths
childGrossRevenue = (CHILDCOST * childTickets);
adultGrossRevenue = (ADULTCOST * adultTickets);
totalGrossRevenue = (childGrossRevenue + adultGrossRevenue);
distributorRevenue = (totalGrossRevenue * .20);
totalNetRevenue = (totalGrossRevenue * .80);
cout << left << "Movie Name:" << setw(20) << right << movieName << endl;
cout << left << "Adult Tickets Sold:" << setw(20) << right << adultTickets << endl;
cout << left << "Child Tickets Sold:" << setw(20) << right << childTickets << endl;
cout << left << "Gross Box Office Revenue:" << setw(20) << right << totalGrossRevenue << endl;
cout << left << "Amount Paid to Distributor:" << setw(20) << right << distributorRevenue << endl;
cout << left << "Net Box Office Revenue:" << setw(20) << right << totalNetRevenue << endl;
system("pause");
return 0;
}
As far as my understanding goes the first cout line should do the following:
Align "Movie Name:" to the left, setw(20) set a 20 space padding between the "Movie Name:" and movieName. right then justifies movieName to the right. Is this correct? Just for clarification this is how I'd like it to look.
(I'm also well aware using system("pause") is sacrilegious before anyone mentions it.)
setw(20) set a 20 space padding between the "Movie Name:" and movieName. right then justifies movieName to the right. Is this correct?
No.
setw(20) sets the next "field" to be 20-characters wide, triggering the insertion of additional whitespace if the field is shorter (resulting in an "alignment" effect in the output of subsequent fields).
This must come before the field is inserted otherwise you have a temporal paradox.
The field you're trying to pad is the "Movie Name:" part, so move your setws one to the left.
left and right align within a field, which doesn't seem to be what you are after, so drop right.
(live demo*)
* I have killed two unused variables, fixed indentation, remove sacrilegiousness (I literally had to or this demo wouldn't work — evil!), and increased your spacing (since 20 isn't actually enough to fit column 1 in all your rows). Otherwise the changes are only as recommended above.

C++ Beginner: How do I prevent the text in my table from pushing any text to the right of it?

I am working on a very basic program for my Fundamentals I class and I have everything 98% working as intended.
This program takes the names of three grades, averages them, and outputs them into a table, but since assignmentName[] is on the same line of code as grade[], it pushes grade[] to the right determining on how many characters the user inputted.
Screenshot of the problem
Here is the code I currently have written for the table:
cout << "___________________________\n";
cout << name << "'s Grade Chart\n";
cout << "---------------------------\n";
cout << setprecision(1) << fixed;
cout << "Grade for " << assignmentName[0] << setw(8) << grade[0] << endl;
cout << "Grade for " << assignmentName[1] << setw(8) << grade[1] << endl;
cout << "Grade for " << assignmentName[2] << setw(8) << grade[2] << endl;
cout << "\nYour average grade between those three assignments is: " << setw(1) << avg << endl;`
I commented, "Place another setw(N) where N is a bit bigger than the largest assignmentName before each << assignmentName."
But on second thought it's bit more fun than that, so I figure a real answer is in order.
First, some reading materials:
Documentation on std::left and std::right
Documentation on std::max
And now on with the show!
First we need to know how big the largest assignment name is.
size_t max = 0;
for (const string & assn: assignmentName)
{
max = std::max(max, assn.length());
// You may need
//max = std::max(max, strlen(assn));
// if you've been forced to resort to barbarism and c-style strings
}
max++; // one extra character just in case we get a really long grade.
Sometimes this can get a lot neater. For example std::max_element can eliminate the need for the loop we used to get the maximum assignment name length. In this case we're looking for the size of the string, not the lexical order of the string, so I think the loop and std::max is a bit easier on the brain.
And now to format, we print the names left-justified and the grades right justified, with the names padded max characters and the grades 8 characters.
cout << "Grade for " << std::left << setw(max) << assignmentName[0]
<< std::right << setw(8) << grade[0] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[1]
<< std::right << setw(8) << grade[1] << '\n'
<< "Grade for " << std::left << setw(max) << assignmentName[2]
<< std::right << setw(8) << grade[2] << '\n';
Note it's now one big cout. This was done mostly for demonstration purposes and because I think it looks better. It doesn't really save you much, if anything, in processing time. What does save time is the lack of endls. endl is actually a very expensive operation because not only does it end a line, but it also flushes. It forces whatever has been buffered in the stream out to the underlying media, the console in this case. Computers are at their best when they can avoid actually going out of the computer until they really have to. Drawing to the screen is way more expensive than writing to RAM or a cache, so don't do it until you have to.
Instead of writing:
"Grade for " << assignmentName[x] << setw[y] << grade(z)
Write:
"Grade for " << setw[a] << assignmentName[x] << setw[y] << grade(z)
Where a is greater than x in each case.
Maybe that should fix it.
Your a should be something like 10 or 15 or something. I hope it works after that. Try it.

cin is eating output stream

#include <iostream>
using namespace std;
void main(int argc, char* argv[])
{
int conversion, hash;
cout << "Select one." << endl;
cout << "0: Radix Method 32" << endl;
cout << "1: Radix Method 64" << endl;
cout << "2: SumUp" << endl;
cin >> conversion;
cout << endl << "Select one." << endl;
cout << "0: Division" << endl;
cout << "1: Multiplication" << endl;
cin >> hash;
cout << "Conversion: " + conversion << endl;
cout << "hash: " + hash << endl;
}
As simple as this is, I'm getting wild output. I feel like it's something obvious but I'm too tired to see it. The number I enter into the variables is the number of characters removed from the next output string. ex:
Select one.
0: Radix Method 32
1: Radix Method 64
2: SumUp
1
Select one.
0: Division
1: Multiplication
2
onversion:
sh:
Press any key to continue . . .
Select one.
0: Radix Method 32
1: Radix Method 64
2: SumUp
5
Select one.
0: Division
1: Multiplication
1
rsion:
ash:
Press any key to continue . . .
Am I crazy or does this make no sense? Am I using cin wrong? I haven't used C++ for a few months, but I can't see anything wrong with it.
cout << "Conversion: " + conversion means to print from conversion elements after the head of the array.
You may want this (change + to <<):
cout << "Conversion: " << conversion << endl;
cout << "hash: " << hash << endl;

File Stream problems

In 2010 Visual C++ Express, I'm using
...
ifstream inFile("inputfile.dat");
double number;
while(inFile >> number)
{
cout << number << endl;
}
...to read 8 numbers stored in a file into the program, and show them on the monitor. It shows them all correctly and as needed, but I need to store each individual number as already specified doubles. From top to bottom,
Customer 1's Identification #
Balance
Payments outstanding
Purchases that have been made
then the other 4 numbers are the same thing just for a different customer. I've tried a ton of different ways to do it, but each come with:
"Run-Time Check Failure #3 - The variable 'variableName' is
being used without being initialized."
and it happens with almost all of the variables. I've searched for anything to help me with this but couldn't seem to find something that would help me to the extent of what I needed.
Assuming that you really want to store these in 8 distinct variables, and not in some aggregate data type:
std::ifstream inFile("inputfile.dat");
double number;
if(inFile >> cust1id >> cust1bal >> cust1pay >> cust1purch >>
cust2id >> cust2bal >> cust2pay >> cust2purch) {
std::cout <<
"Customer 1's Identification #: " << cust1id << "\n" <<
"Balance: " < cust1bal << "\n" <<
"Payments outstanding: " << cust1pay << "\n" <<
"Purchases that have been made: " << cust1purch <<
"Customer 2's Identification #: " << cust2id << "\n" <<
"Balance: " < cust2bal << "\n" <<
"Payments outstanding: " << cust2pay << "\n" <<
"Purchases that have been made: " << cust2purch << "\n";
}

Align cout format as table's columns

I'm pretty sure this is a simple question in regards to formatting but here's what I want to accomplish:
I want to output data onto the screen using cout. I want to output this in the form of a table format. What I mean by this is the columns and rows should be properly aligned. Example:
Test 1
Test2 2
Iamlongverylongblah 2
Etc 1
I am only concerned with the individual line so my line to output now (not working) is
cout << var1 << "\t\t" << var2 << endl;
Which gives me something like:
Test 1
Test2 2
Iamlongverylongblah 2
Etc 1
setw.
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
cout << setw(21) << left << "Test" << 1 << endl;
cout << setw(21) << left << "Test2" << 2 << endl;
cout << setw(21) << left << "Iamlongverylongblah" << 2 << endl;
cout << setw(21) << left << "Etc" << 1 << endl;
return 0;
}
I advise using Boost Format. Use something like this:
cout << format("%|1$30| %2%") % var1 % var2;
You must find the length of the longest string in the first column. Then you need to output each string in the first column in a field with the length being that of that longest string. This necessarily means you can't write anything until you've read each and every string.
you can do it with
string str = "somthing";
printf ("%10s",str);
printf ("%10s\n",str);
printf ("%10s",str);
printf ("%10s\n",str);