Is there a way to observe values of variables in each iteration? - c++

I'm new to learning how to code and I was wondering if there's a way to see values during each iteration of a loop. Here's a code I'm trying to understand. I know some of it but as it gets deeper, I get confused.
#include <iostream>
#include <string>
using std::cin; using std::endl;
using std::cout; using std::string;
int main()
{
cout << "Please enter your first name: ";
string name = "Jae";
const string greeting = "Hello, " + name + "!";
const int pad = 1;
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
cout << endl;
for (int r = 0; r != rows; ++r) {
string::size_type c = 0;
while (c != cols) {
if (r == pad + 1 && c == pad + 1) {
cout << greeting;
c += greeting.size();
} else {
if (r == 0 || r == rows - 1 ||
c == 0 || c == cols - 1)
cout << "*";
else
cout << " ";
++c;
}
}
cout << endl;
}
}

You can debug your code. If you debug, you can see values during each iteration of a loop

if r is your iterator, write inside the loop this line:
cout << r;

Google is your friend.
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide
Simply you can execute your program line-by-line by pressing F10 key. And hovering mouse over variables shows their current value.

Related

Accelerated C++ Exercise 2.4

I've been following Accelerated C++ for a couple of weeks now but I have been stuck at exercise 2.4 for a while and finally I thought I found it out but after trying giving it different dimensions I found out that it doesn't really work and I don't really understand why
The code initially prints a framed message, in this particular exercises I was supposed to change how the code prints the blanks from one character at a time into writing all the planks at once
here is the code:
// [2-0, 2-4] Exercises
#include<iostream>
#include<string>
// saying what standard-library names we use
using std::cout; using std::endl;
using std::cin; using std::string;
int main()
{
// asking for the name
cout << "Please enter your first name: ";
// reading the name
string name;
cin >> name;
// building the message that we intend to write
const string greeting = "Hello, " + name + "!";
// 2.2 & 2.3 asking for inpadY
cout << "Please enter the number of padY (Vertical padding): ";
// 2.2 & 2.3 reading the inpadY
int inpadY;
cin >> inpadY;
// 2.2 & 2.3 asking for inpadX
cout << "Please enter the number of padX (Horizontal padding): ";
// 2.2 & 2.3 reading the inpadX
int inpadX;
cin >> inpadX;
// the number of planks surrounding the greeting
// 2.2 & 2.3 added inpadY as the number of planks;
const int padY = inpadY;
// 2.2 & 2.3 added inpadX
const int padX = inpadX;
// 2.4 pad size
const int pad = inpadX + inpadY;
// the number of rows and columns to write
const int rows = padY * 2 + 3;
const string::size_type cols = greeting.size() + padX * 2 + 2;
// 2.4 creating a padding string left and right and top and bottom
const string LeftRightPad(padY, ' ');
const string TopBottomPad(cols - 2, ' ');
// write a blank line to separate the output and the input
cout << endl;
// write rows rows of output
// invariant: we have written r rows so far
for (int r = 0; r != rows; ++r) {
string::size_type c = 0;
// invariant: we have written c characters so far in the current row
while (c != cols) {
// is it time to write the greeting?
if (r == padY + 1 && c == padX + 1)
{
cout << greeting;
c += greeting.size();
} else {
// are we on the border?
if (r == 0 || r == rows - 1 ||
c == 0 || c == cols - 1)
{cout << "*";
++c;}
else
// 2.4 typing out the spaces at once
{cout << LeftRightPad;
c += LeftRightPad.size();}
}
}
cout << endl;
}
return 0;
}
Edited to have the input and output
Please enter your first name: Estrogen
Please enter the number of padY (Vertical padding): 2
Please enter the number of padX (Horizontal padding): 2
**********************
* *
* *
* Hello, Estrogen! *
* *
* *
**********************
Process returned 0 (0x0) execution time : 3.281 s
Press any key to continue.
Please enter your first name: Estrogen
Please enter the number of padY (Vertical padding): 2
Please enter the number of padX (Horizontal padding): 5
****************************
* *
* *
* *
* *
* *
****************************
Process returned 0 (0x0) execution time : 5.098 s
Press any key to continue.
Please enter your first name: Estrogen
Please enter the number of padY (Vertical padding): 3
Please enter the number of padX (Horizontal padding): 2
**********************
*
*
*
*
*
*
*
**********************
Process returned 0 (0x0) execution time : 4.333 s
Press any key to continue.
Update: I've rewritten the code and the output is an infinite loop of asterisks here is the new code
#include<iostream>
#include<string>
using std::string; using std::endl;
using std::cout; using std::cin;
int main()
{
cout << "Please enter your first name: ";
string name;
cin >> name;
const string message = "Hello, " + name + "!";
cout << "Enter the length: ";
int length;
cin >> length;
cout << "Enter the height: ";
int height;
cin >> height;
const int rows = height * 2 + 3;
const string::size_type cols = message.size() + length * 2 + 2;
const string TopBottom(cols, '*');
const string Blank(cols - 2, ' ');
const string messageblank(cols - 3 - message.size(), ' ');
cout << endl;
for (int r = 0; r != rows; ++r) {
string::size_type c = 0;
while (c != cols) {
if ( r == height + 1 && c == length + 1)
{
cout << messageblank << message << messageblank;
c += Blank.size();
} else
if (r == 0 && c == 0 || r == rows - 1 && c == cols -1)
{
cout << TopBottom;
c += TopBottom.size();
} else
if ( r != 0 && c == 0 || r != rows -1 && c == cols - 1)
{
cout << "*";
++c;
} else
cout << Blank;
c += Blank.size();
}
cout << endl;
}
return 0;
}
Thank you guys for help in advance
Unless the code is supposed to be written this way, I would propose another, row by row approach:
print_frame_row(cols);
for (int i = 0; i < padY; ++i)
print_v_padding(cols);
print_greeting(padX, greeting);
for (int i = 0; i < padY; ++i)
print_v_padding(cols);
print_frame_row(cols);
where
void print_frame_row(int cols)
{
std::cout << std::string(cols, '*') << '\n';
}
void print_v_padding(int cols)
{
const std::string h_padding(cols - 2, ' ');
std::cout << '*' << h_padding << "*\n";
}
void print_greeting(int padX, const std::string &msg)
{
const std::string h_padding(padX, ' ');
std::cout << '*' << h_padding << msg << h_padding << "*\n";
}
This way you have a simpler logic, and need not worry about counting columns or deciding when to write each character.
ok so it took me 3 days but I finally figured it out here is the working code
#include<iostream>
#include<string>
using std::string; using std::endl;
using std::cout; using std::cin;
int main()
{
cout << "Please enter your first name: ";
string name;
cin >> name;
cout << "Enter the length: ";
int length;
cin >> length;
cout << "Enter the height: ";
int height;
cin >> height;
const string message = "Hello, " + name + "!";
const int rows = height * 2 + 3;
const string::size_type cols = message.size() + length * 2 + 2;
const string TopBottom(cols, '*');
const string Blank(cols - 2, ' ');
const string messageblank(length, ' ');
cout << endl;
for (int r = 0; r != rows; ++r) {
string::size_type c = 0;
while (c != cols) {
if ( r == height + 1 && c == 0)
{
cout << "*" << messageblank << message << messageblank << "*";
c += TopBottom.size();
} else
if (r == 0 && c == 0 || r == rows - 1 && c == 0)
{
cout << TopBottom;
c += TopBottom.size();
} else
if ( c == 0 && r != 0 || c == 0 && r != rows - 1)
{
cout << "*" << Blank << "*";
c += TopBottom.size();
}
}
cout << endl;
}
return 0;
}

generating a box of stars surrounding text with for loops in c++

I'm trying to make a program in c++ which surrounds some given lines of code with a box of stars in which the sentences fit 'neatly'. I've done this for a small text which consists of only the same sentence and it works. But when trying to make this program work for texts with more than only one sentence it fails because the sentences aren't all the same size. How can I fix this issue? Here's my code
#include <iostream>
using namespace std;
int main( int argc, char* argv[] )
{
int r, c;
for( r = 0; r < 5; ++r )
{
for( c = 0; c < 28; ++c )
{
if( r == 0 || r == 4 )
{
cout << "*";
}
else
{
if( c == 0 || c == 27 )
cout << "*";
if(r >= 1 && c == 1){
cout << " this is a test sentence";
}
if(c > 1 && c < 4){
cout << " ";
}
}
}
cout << "\n";
}
return 0;
}
You might change your code, so that it uses variables, not literal constants. After you do that, you have two options based on how you want to calculate the width of the box:
fixed - use cout << std::setw(fixed_width) << std::left << sentences[i]; (in a loop)
variable - use loop or std::max_element to determine the longest sentence and do the same thing as with fixed width
where you'll use std::vector<std::string> sentences.
I'll also add how neat can be what you currently have:
#include <iostream>
#include <string>
#include <iomanip>
using std::cout;
using std::endl;
int main()
{
const int width = 20;
const char c = '*';
std::string horizontal_line(width, c);
std::string horizontal_line_empty(c + std::string(width - 2, c) + c);
cout << horizontal_line << endl << horizontal_line_empty << endl;
cout << c << std::setw(width - 2) << std::left << std::string("hello") << c << endl;
cout << horizontal_line_empty << endl << horizontal_line << endl;
}
I hope you'll get something from it.

c++ calculations in the nested for loop

I've been trying to do this program but I'm stuck, I'm still a beginner, any help would be appreciated.
I need the program to do
Print a 10 X 10 table in which each entry in the table is the sum of the row and column number
Include an accumulator that will calculate the sum of all the table entries.
what I'm having a problem with is when I try to calculate the row and column for each entry and the total sum.
Each time I put any calculation in the nested for loop it messes up. Here's with no calculations:
Here's with the calculations:
The code:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
// r= row, c= column, s= sum(row+column), ts= sum of all entries
int r, c, s = 0, ts = 0;
for (r = 1; r <= 10; r++)
{
for (c = 1; c <= 10; c++)
s = r + c; ** This one
ts = ts + s; ** and this
cout << setw(3) << c;
cout << endl;
}
cout << "the total sum of all table entries is " << ts << endl;
system("pause");
return 0;
}
Note that a loop will repeat the next statement. When you do it "without calculations", I assume you mean
for (c = 1; c <= 10; c++)
cout << setw(3) << c;
cout << endl;
Here, the first cout statement is repeated and prints out the table in your first screenshot. (Notice the indentation here which indicates what code is "inside" the for loop.)
Now when you add the calculations, you have
for (c = 1; c <= 10; c++)
s = r + c; ** This one
ts = ts + s; ** and this
cout << setw(3) << c;
cout << endl;
Even if you indent to show what you intend to repeat, the program will only repeat the statement immediately following the for loop header. In this case, you are repeating the calculation s = r + c; over and over. (Since this result is never used, the compiler most likely just throws it away.)
In order to repeat multiple statements, you need to wrap them in a "compound statement" which means using curly braces:
for (c = 1; c <= 10; c++)
{
s = r + c; ** This one
ts = ts + s; ** and this
cout << setw(3) << s;
}
cout << endl;
I also assume that you want to print out the sum of the row and column.
I strongly suggest that you always use curly braces, even when you repeat a single statement. This makes it easier to add more statements inside a loop because you don't have to remember to add the curly braces later.
I think you need to enclose the inner loop in curly brackets like so:
for (r = 1; r <= 10; r++)
{
for (c = 1; c <= 10; c++)
{
s = r + c;
ts = ts + s;
cout << setw(3) << c;
cout << endl;
}
}
Otherwise you will only run the
s = r + c;
line in the inner loop.
You need a pair of curly brackets for your for loop
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int r, c, s = 0, ts = 0; // r= row, c= column, s= sum(row+column), ts= sum of all entries
for (r = 1; r <= 10; r++)
{
for (c = 1; c <= 10; c++) { // <- was missing
s = r + c; ** This one
ts = ts + s; ** and this
cout << setw(3) << c;
cout << endl;
} // <- was missing
}
cout << "the total sum of all table entries is " << ts << endl;
system("pause");
return 0;
}
Without the {}, only s = r + c will be considered part of the for loop.
Incidentally this is the cause of the goto fail bugs: http://martinfowler.com/articles/testing-culture.html

Convert integers to characters [duplicate]

This question already has answers here:
How to convert a number to string and vice versa in C++
(5 answers)
Closed 9 years ago.
I am trying to get my program to print letters instead of numbers. I used char c = static_cast<char>(N); to attempt to do this but it wont work, instead it prints character images that are not (a-z) How can I get the numbers to be printed as letters?
#include <cstdlib>
#include <iostream>
using namespace std;
// Function getUserInput obtains an integer input value from the user.
// This function performs no error checking of user input.
int getUserInput()
{
int N(0);
cout << endl << "Please enter a positive, odd integer value, between (1-51): ";
cin >> N;
if (N < 1 || N > 51 || N % 2 == 0)
{
cout << "Error value is invalid!" << "\n";
cout << endl << "Please enter a positive, odd integer value, between (1-51): ";
cin >> N;
system("cls");
}
cout << endl;
return N;
} // end getUserInput function
// Function printDiamond prints a diamond comprised of N rows of asterisks.
// This function assumes that N is a positive, odd integer.
void printHourglass(int N)
{
char c = static_cast<char>(N);
for (int row = (N / 2); row >= 1; row--)
{
for (int spaceCount = 1; spaceCount <= (N / 2 + 1 - row); spaceCount++)
cout << ' ';
for (int column = 1; column <= (2 * row - 1); column++)
cout << c;
cout << endl;
} // end for loop
// print top ~half of the diamond ...
for (int row = 1; row <= (N / 2 + 1); row++)
{
for (int spaceCount = 1; spaceCount <= (N / 2 + 1 - row); spaceCount++)
cout << ' ';
for (int column = 1; column <= (2 * row - 1); column++)
cout << c;
cout << endl;
} // end for loop
// print bottom ~half of the diamond ...
return;
} // end printDiamond function
int main()
{
int N = 1;
while (N == 1)
{
printHourglass(getUserInput());
cout << endl;
cout << "Would you like to print another hourglass? ( 1 = Yes, 0 = No ):";
cin >> N;
}
} // end main function
The letters are not numbered with A starting at 1 or anything like that. You're likely on an ASCII/UTF-8 system. So, in printHourglass, replace cout << N with
cout << static_cast<char>('A' + count - 1);
C functions, itoa
C++, using stringstream
boost::lexical_cast
Actually for your case, you can directly print it out. cout << N

While() Loop to create a border of asterisks around text?

Okay, I'm new at programming and decided to jump into this book called Accelerated C++. I'm only on the second chapter and I tried following the exercise, which is to create a program that asks for your name and then output it with a frame around it and padding.
When I execute it, it doesn't seem to be moving onto the next row. I'm guessing it's to do with my while() loop but I'm too dumb to figure out what it is exactly
// ask for a person's name, and greet the person
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::string;
int main()
{
// fetch name
cout << "Please enter your first name: ";
string name;
cin >> name;
// message
const string greeting = "Hello, " + name + "!";
// padding
const int pad = 1;
//desired rows/columns
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
// seperate output from input
cout << std::endl;
// invariants
int r = 0;
string::size_type c = 0;
while (r != rows) {
while(c != cols) {
if (r == 0 || r == rows -1 || c == 0 || c == cols -1) { // if in bordering column or row
cout << "*"; //output *
} else {
if (r == pad + 1 && c == pad + 1) { //if on row for greeting
cout << greeting; // write greeting
c += greeting.size(); // adjust invariant
} else {
cout << " ";
}
}
++c;
}
++r;
cout << std::endl;
}
return 0;
}
Consider moving the column counter c to nearer where you use it, then as tuckermi says it will start at 0 for each row.
while (r != rows) {
string::size_type c = 0;
while(c != cols) {
At the bottom of your outer loop you need to reset the variable c to zero, otherwise it keeps its old value and won't re-enter the inner loop.
A good way to accomplish this is to move the definition/initialization of the variable into the beginning of the outer loop. That way c will be reinitialized before you start the inner loop each time.
You're almost there.
You need to clear c each row, and you need to take one off the greetings.size() to make it format properly (accounting for the fact you will be incrementing it later in the loop)
// ask for a person's name, and greet the person
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::string;
int main()
{
// fetch name
cout << "Please enter your first name: ";
string name;
cin >> name;
// message
const string greeting = "Hello, " + name + "!";
// padding
const int pad = 1;
//desired rows/columns
const int rows = pad * 2 + 3;
const string::size_type cols = greeting.size() + pad * 2 + 2;
// seperate output from input
cout << std::endl;
// invariants
int r = 0;
while (r != rows) {
string::size_type c = 0;
while(c != cols) {
if (r == 0 || r == rows -1 || c == 0 || c == cols -1) { // if in bordering column or row
cout << "*"; //output *
} else {
if (r == pad + 1 && c == pad + 1) { //if on row for greeting
cout << greeting; // write greeting
c += (greeting.size()-1); // adjust invariant
} else {
cout << " ";
}
}
++c;
}
++r;
cout << std::endl;
}
return 0;
}
http://ideone.com/mb9InW
Apart from reseting the variable c in the outer loop, you are not getting padding between the asterick and the message. So for that include the below code just after where you are printing the message.
for(int i = 0;i<pad;i++)
{
cout<<" ";
}