Rectangular shape with characters inside it placed with a certain width - c++

I am trying to replicate this:
Type the height and width of the rectangle: 10 13
+-------------+
| w w w |
| w w w |
| w w w |
|w w w w|
| w w w |
| w w w |
| w w w |
|w w w w|
| w w w |
| w w w |
+-------------+
Type the height and width of the rectangle: 0 0
+-+
+-+
Type the height and width of the rectangle: 4 1
+-+
| |
| |
| |
|w|
+-+
I succesfully made a subprogram that printed out the rectangle (though it is messy and there's obvious duplications of code). How can I, in the same subprogram (or maybe in a different one) print out the 'w' and the empty spaces filled with spaces? The width of each 'w' is 4 spaces. I kind of have an idea. That we do cout << setfill(' ') << setw(4) << 'w' and then an if-statement that if the setw exceeds <= width it will do a '\n'
However this is my code and I would much appreciate how my code could be improven and how to implement a character with width 4 inside the rectangle.
#include <iostream>
#include <iomanip>
using namespace std;
void print_rectangle (int const width,
int const height)
{
cout << '+' << '-';
for (int i {1}; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
for (int j {}; j < height; ++j)
{
cout << '|' << setw(width + 1) << '|' << endl;
}
cout << '+' << '-';
for (int i {1}; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
}
int main()
{
int width {};
int height {};
cout << "Enter the height and width of the rectangle: ";
cin >> height;
cin >> width;
print_rectangle(width,height);
return 0;
}

Well the solution for the second part which will print the 'w' and the spaces is as follows:
#include <iostream>
#include <iomanip>
using namespace std;
void print_rectangle (int const width,
int const height)
{
int counter=1;
int remainder= (width+1) % height;
cout << '+' << '-';
for (int i = 1; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
for (int j =0 ; j < height; ++j)
{
if(j == 0 || j == height )
cout << '|' << setw(width + 1) << '|' << endl;
else
{
cout << '|';
for (int i = 0; i <width ; i++)
{
if(counter % remainder == 0)
cout<<"w";
else
cout<<" ";
counter++;
}
cout << '|'<<endl;
}
}
cout << '+' << '-';
for (int i =1 ; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
}
int main()
{
int width =0;
int height =0;
cout << "Enter the height and width of the rectangle: ";
cin >> height;
cin >> width;
print_rectangle(width,height);
return 0;
}
I have tested the given input cases on it as well and it gives the right output. What's happening here is that the remainder of height and width+1 gives us a remainder and with the help of that remainder we are going to print w's. A counter is incremented in the loop and whenever that counter is a multiple of that remainder w will be printed otherwise space.
Here is the output of the test case input 4 and 1 output
And here is the output of test case input 10 and 13

Please learn split problem to smaller pieces which are a small functions.
Take a look on this:
using std::setw;
void print_ending(std::ostream& out, int const width) {
out << '+' << std::string(width, '-') << '+' << '\n';
}
void print_row(std::ostream& out,
int const width,
int const period,
int offset) {
out << '|' << std::string(std::min(width, offset), ' ');
if (offset < width) {
out << 'w';
auto remainin_width = width - offset - 1;
for (int i = remainin_width / period; i > 0; --i) {
out << setw(period) << 'w';
}
out << std::string(remainin_width % period, ' ');
}
out << "|\n";
}
void print_rectangle(std::ostream& out,
int const width,
int const height,
int period = 4) {
print_ending(out, width);
for (int j{}; j < height; ++j) {
print_row(out, width, period, (height - j) % period);
}
print_ending(out, width);
}
Live demo

Related

Print out the alphabet using for loop and setw

When I compile my program, run it and enter values I will get a rather strange and unexpected output:
So if I enter:
Enter width and height: 9 5
Enter characters: X O
1 XOXOXOXOX
2 OXOXOXOXO
3 XOXOXOXOX
4 OXOXOXOXO
5 XOXOXOXOX
A BCDEFGHI
When it's supposed to be:
Enter width and height: 9 5
Enter characters: X O
1 XOXOXOXOX
2 OXOXOXOXO
3 XOXOXOXOX
4 OXOXOXOXO
5 XOXOXOXOX
ABCDEFGHI
When do my void print_alphabet in another program it will work out just fine so I don't know the problem. I believe it has something to do with my other function but I can not seem to get it to work. Why does it act that way? Why does it print out A and then it does setw and prints out the rest?
This is my code:
#include <iostream>
#include <iomanip>
using namespace std;
void print_chess_board (int const height,
int const width,
char const char_1,
char const char_2)
{
int index {};
for (int i = 1; i <= height; ++i)
{
if (i%2)
{
index = 0;
}
else
{
index = 1;
}
cout << left << setw(3) << i;
for (int j {}; j < width; ++j)
{
if (++index%2 == 0)
{
cout << char_2;
}
else
{
cout << char_1;
}
}
cout << endl;
}
}
void print_alphabet (int const width)
{
cout << setfill(' ') << setw(4);
for (int i {}; i < width; ++i)
{
cout << char('A' + i);
}
}
int main()
{
int width {};
int height {};
char char_1 {};
char char_2 {};
cout << "Enter width and height: ";
cin >> width >> height;
cout << "Enter characters: ";
cin >> char_1 >> char_2;
print_chess_board(height,width,char_1,char_2);
print_alphabet(width);
return 0;
}
You need to change
cout << setfill(' ') << setw(4);
to
cout << right << setfill(' ') << setw(4);

Print out a text in the middle of a rectangle

I want to print out a rectangle and in the middle I want to output a preferred text.
So In the terminal it should look like:
Enter width and height: 5 6
+-----+
| |
| |
| |
| |
| |
+-----+
Then in the middle of the rectangle (height/2) it should print out "Hey". It doesn't fit in this example because the format on reddit is a bit different than my compiler.
However I wonder how I could make this happen? I can create the rectangle but I cannot seem to create a "when" statement, as in "when mid occurs, print out "Hey".
I need help finding a way to write such statement.
Here is my code:
#include <iostream>
#include <iomanip>
using namespace std;
void print_row (int const width)
{
cout << '+' << '-';
for (int i = 1; i < width; ++i)
{
cout << '-';
}
cout << '+' << endl;
}
void print_rectangle (int const width, int const height)
{
int mid = height/2;
print_row(width);
for (int i {}; i < height; ++i)
{
cout << '|' << setw(width+1) << '|' << endl;
if (mid)
{
cout << "Hey" << endl;
}
}
print_row(width);
}
int main()
{
int width {};
int height {};
cout << "Enter width and height: ";
cin >> width >> height;
print_rectangle(width,height);
return 0;
}
first of all validate your width and height in your print_rectangle
String output = "hey";
if(width < output.length() || height <= 0) return;
and change the for loop like this
for (int i = 0; i < height; ++i) {
if (i == mid) {
int spacing = width - output.length();
cout <<'|'<< setw(width-spacing/2) << output << setw(spacing/2+1) << '|' << endl;
continue;
}
cout << '|' << setw(width+1) << '|' << endl;
}

creating a hollow rectangle

My assignment is to allow for user input of width, height, and character, in order to create a hollow rectangle. I am hitting a wall in my coding, For some reason, my rectangle doesn't have a "top" and the right side isn't on the correct column. I am fairly new to C++, so any criticism you may have is welcomed!
Below is my code and the output that I receive.
#include <iostream>
using namespace std;
int main()
{
int i, j, height, width;
char ch;
char cont ='Y';
while (cont=='Y' || cont=='y')
{
cout << "Enter desired height (3 to 20): ";
cin >> height;
while (height > 20 || height < 3 )
{
cout<<"Illegal entry. Please enter height value from 3 to 20: ";
cin >> height;
}
cout <<"Enter desired width (3 to 20): ";
cin >> width;
while (width > 20 || width < 3)
{
cout<<"Illegal entry. Please enter width value from 3 to 20: ";
cin >> width;
}
cout << "What character would you like to set as your border?: ";
cin >> ch;
for(int i = 1; i <= height; i++) {
if(width <= 1)
for(int i = 1; i <=width; i++) {
cout << " " << ch;
}
else if(i < height) {
cout << endl;
for(int j = 1; j <= width; j++) {
if(j == 1 || j == width)
cout << " " << ch;
else
cout << " ";
}
}
else {
cout<< endl;
for(int k = 1; k <= width; k++)
{
cout <<" "<< ch;
}
}
}
cout<<"\nDo you want to continue? (Y): ";
cin >> cont;
}
cout <<"\nYou are done here, good job.\n";
cout <<'\n';
}
While I won't get into the code itself, think about what you want to accomplish first, and then write the loops. (I suggest using row and col as variable names.)
Since you need a hollow rectangle and you are taking in a desired width and height we know the following (w and h being input amounts.)
So do the following prints in order:
You need a row of * with length w.
You need h - 2 rows of * that have w - 2 spaces between them.
You need another row like 1.
Do these in order and you will have your hollow rectangle.
Example input: w = 5, h = 7.
So we have:
***** // Step 1.
* * // Step 2. Note there are 5 - 2 spaces between them. (w - 2).
* *
* *
* *
* *
***** // Step 3.
While you already have a good answer, you are not making use of the C++ language functions that would make the task much easier, and more importantly, you are not validating your input correctly. For example, try the following:
> McNiel CSC 2050.exe
Enter desired height (3 to 20): No, I don't think I will
Things go wildly spinning out of control quickly.
Generally, when you want to validate user input and ensure you receive values within a specific range, you simply want a continual loop, where you prompt, validate the input, check/handle the stream states .eof(), .bad() and .fail() (see: std::basic_iostream) and empty any remaining characters in your input buffer before your next read attempt.
An example for your h x w input loop would be similar to the following (note, both h and w are read at the same time, you are free to use two loops if you like):
int h, w;
for (;;) {
std::cout << "enter height & width (3 <= h w <= 20): ";
if (!(std::cin >> h >> w)) {
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "(user canceled/unrecoverable error)\n";
return 1;
}
else if (std::cin.fail()) {
std::cerr << "error: invalid integer input.\n";
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
}
}
else if (3 <= h && h <=20 && 3 <= w && w <= 20)
break;
else
std::cerr << "error: h or w not within (3 <= x <= 20)\n";
}
See std::basic_istream::ignore for details on emptying the input stream and std::basic_ios::clear.
Next, rather than some loop scheme outputting spaces, you simply need to make use of std::setw to handle the spacing between the '*' to make your hollow rectangle. The top and bottom are solid, but for the middle rows, all you need to do is std::cout << '*' << std:setw(w-1) << '*';. For example your entire output loop reduces to:
for (int i = 0; i < h; i++) {
if (!i || i == h - 1)
for (int j = 0; j < w; j++)
std::cout << '*';
else
std::cout << '*' << std::setw(w-1) << '*';
std::cout << '\n';
}
Putting it altogether, you can do something similar to the following:
#include <iostream>
#include <iomanip>
#include <limits>
int main (void) {
int h, w;
for (;;) {
std::cout << "enter height & width (3 <= h w <= 20): ";
if (!(std::cin >> h >> w)) {
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "(user canceled/unrecoverable error)\n";
return 1;
}
else if (std::cin.fail()) {
std::cerr << "error: invalid integer input.\n";
std::cin.clear();
std::cin.ignore (std::numeric_limits<std::streamsize>::max(),'\n');
}
}
else if (3 <= h && h <=20 && 3 <= w && w <= 20)
break;
else
std::cerr << "error: h or w not within (3 <= x <= 20)\n";
}
for (int i = 0; i < h; i++) {
if (!i || i == h - 1)
for (int j = 0; j < w; j++)
std::cout << '*';
else
std::cout << '*' << std::setw(w-1) << '*';
std::cout << '\n';
}
}
Example Use/Output
$ ./bin/hollowrect
enter height & width (3 <= h w <= 20): No, I don't think I will
error: invalid integer input.
enter height & width (3 <= h w <= 20): OK
error: invalid integer input.
enter height & width (3 <= h w <= 20): 10 2
error: h or w not within (3 <= x <= 20)
enter height & width (3 <= h w <= 20): 10 3
***
* *
* *
* *
* *
* *
* *
* *
* *
***
A second h x w example:
$ ./bin/hollowrect
enter height & width (3 <= h w <= 20): 3 10
**********
* *
**********
User cancels with manual EOF:
$ ./bin/hollowrect
enter height & width (3 <= h w <= 20): help
error: invalid integer input.
enter height & width (3 <= h w <= 20): (user canceled/unrecoverable error)
Look things over and let me know if you have further questions.
if you want to below result when assign height and width is 4.
* * * *
* *
* *
* * * *
your for loop is wrong, using this code in your for loop.
for(int i = 1; i <= height; i++) {
if( i == 1 || i == height) {
for (int j = 1; j <= width; j++) {
std::cout << ch << " ";
}
std::cout << std::endl;
} else {
for (int j = 1; j <= width; j++) {
if( j == 1 || j == width) {
std::cout << ch << " ";
} else {
std::cout << " ";
}
}
std::cout << std::endl;
}
}

C++: How do I make this shape from this code?

I am trying to make this shape from the code below. I'm confused as to how to make it print the 2nd row, second to last star without it skipping and printing the extra space before printing the star. Once that is figured out would the bottom half, when the stars expands back out, would the code be similar to the top half? I have tried a couple combinations of code between c and r but I have been stuck with what I currently.
---------------------- //row 0
* *| //row 1
* * * *| //row 2
* * * * * *|
* * * * * * * *|
* * * * * * * * * *|
* * * * * * * * * * *|
* * * * * * * * * *|
* * * * * * * *|
* * * * * *|
* * * *|
* *|
----------------------
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
cout << "Enter a positive odd number less than 40: ";
int num = 0;
int z = 1;
for (int a = 0; a < 3; ++a)
{
cin >> num;
if (num < 38 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl << endl;
for (int r = 0; r < num; ++r) //outer loop/rows
{
for (int c = 0; c < num; ++c) //inner loop/columns
{
if (r == 0) cout << "--"; //top of square
else if (c >= r + r - c && c < num - 1)
cout << " ";
//else if (c == num - 1) cout << "*|";
else if (r == num - 1) cout << "--"; //bottom of square
else if (c == num - 1) cout << "*|"; //right side of square
else if (r > c) cout << "* ";
}
cout << endl;
}
break;
}
else cout << "Please enter a positve odd number that is less than 40!" << endl;
}
cout << endl;
}
I just took two variables left=0 & right=num-1 and increased left & decreased right till r<=num/2, after that i reversed the process,when the col <= left or col >=right I printed *.
I hope it will be easy to understand.
Here is the code:
#include <iostream>
using std::cout; using std::cin; using std::endl;
int main() {
cout << "Enter a positive odd number less than 40: ";
int num = 0;
int z = 1;
for (int a = 0; a < 3; ++a)
{
cin >> num;
if (num < 38 && num > 0 && num % 2 == 1)
{
cout << "Thank you!" << endl << endl;
int left=0,right=num-1;
//for printing top line
for(int i = 0; i < num; i++) cout<<"- ";
cout<<"-"<<endl;
for (int r = 0; r < num; ++r) //outer loop/rows
{
//printing columns
for(int c = 0; c < num; c++)
{
if(c <= left || c >= right)
cout<<"* ";
else
cout<<" ";
}
if(r >= num/2) //checking for half of the rows
{
left--;right++;
}
else
{
left++;right--;
}
cout<<"|"<<endl;
}
//for printing last additional line
for(int i = 0; i < num; i++) cout<<"- ";
cout<<"-"<<endl;
break;
}
else cout << "Please enter a positve odd number that is less than 40!" << endl;
}
cout << endl;
}
This approach does it the math way.
Furthermore it draws a full frame with plus-chars at the edges.
Give it a try.
#include <iostream>
#include <cmath>
using std::cout; using std::cin; using std::endl;
int main() {
cout << "Enter a positive odd number less than 40: ";
int num = 0;
int z = 1;
for (int a = 0; a < 3; ++a) {
cin >> num;
if (num < 40 && num > 0 && num % 2 == 1) {
cout << "Thank you!" << endl << endl;
int center = ceil(num / 2.0);
for (int r = 0; r <= num+1; ++r) { //outer loop/rows
for (int c = 0; c <= num+1; ++c) { //inner loop/columns
if (r == 0 || r == num+1) {
if (c == 0 || c == num+1)
cout << "+"; // corner
else
//top or botton of square between corners
if (c == center)
cout << "-";
else
cout << "--";
}
else if (c == 0 || c == num+1) {
cout << "|"; // left or right frame
} else {
// inner part
if ((center-std::abs(center-r)) >= center-std::abs(center-c))
if (c < center)
cout << "* ";
else if (c > center)
cout << " *";
else
cout << "*";
else
if (c == center)
cout << " ";
else
cout << " ";
}
}
cout << endl;
}
} else
cout << "Please enter a positve odd number that is less than 40!" << endl;
}
cout << endl;
}
Just another way (with some more user input checking):
#include <iostream>
#include <string>
#include <limits>
#include <sstream>
using std::cout;
using std::cin;
using std::string;
const auto ssmax = std::numeric_limits<std::streamsize>::max();
const int max_dim = 40;
const int max_iter = 3;
int main() {
cout << "Enter a positive odd number less than " << max_dim << ": ";
int num = 0, counter = 0;
while ( counter < max_iter ) {
cin >> num;
if ( cin.eof() )
break;
if ( cin.fail() ) {
cout << "Please, enter a number!\n";
cin.clear();
cin.ignore(ssmax,'\n');
}
if ( num < max_dim && num > 0 && num % 2 ) {
cout << "Thank you!\n\n";
//top line
string line(num * 2, '-');
cout << line << '\n';
for ( int r = 0, border = num - 1; r < num; ++r ) {
cout << '*';
for ( int c = 1; c < num; ++c ) {
if ( (c > r && c < border) || (c < r && c > border) )
cout << " ";
else
cout << " *";
}
// right border
cout << "|" << '\n';
--border;
}
//bottom line
cout << line << '\n';
++counter;
} else {
cout << "Please, enter a positive odd number that is less than 40!\n";
}
}
cout << std::endl;
}
Or my favorite:
// top line
string line = string(num * 2, '-') + '\n';
cout << line;
// inside lines
int r = 0, border = ( num - 1 ) * 2;
string inside = string(border + 1, ' ') + "|\n";
// top
while ( r < border ) {
inside[r] = '*';
inside[border] = '*';
r += 2;
border -= 2;
cout << inside;
}
// center line
inside[r] = '*';
cout << inside;
// bottom
while ( border > 0 ) {
inside[r] = ' ';
inside[border] = ' ';
r += 2;
border -= 2;
cout << inside;
}
//bottom line
cout << line;

How to make exception in for loop?

The code below prints a box with the intergers the user inputs. I need to make it hollow to only display the full length of the first and last line of the box. like width = 5 height = 4
Example Output:
00000
0 0
0 0
00000
Source:
int main ()
{
int height;
int width;
int count;
int hcount;
string character;
cout << "input width" << endl;
cin >> width;
cout << "input height" << endl;
cin >> height;
cout << "input character" << endl;
cin >> character;
for (hcount = 0; hcount < height; hcount++)
{
for (count = 0 ; count < width; count++)
cout << character;
cout << endl;
}
}
I do not know how to change the loop condition for the width to make it work.
I think you can test whether you are in the first or last row, and first or last column.
Example:
#include <string>
#include <iostream>
int main ()
{
using namespace std; // not recommended
int height;
int width;
string character;
cout << "input width" << endl;
cin >> width;
cout << "input height" << endl;
cin >> height;
cout << "input character" << endl;
cin >> character;
for (int i = 0; i < height; i++)
{
// Test whether we are in first or last row
std::string interior_filler = " ";
if (i == 0 || i == height - 1)
{
interior_filler = character;
}
for (int j = 0; j < width; j++)
{
// Test whether are in first or last column
if (j == 0 || j == width -1)
{
cout << character;
} else {
cout << interior_filler;
}
}
// Row is complete.
cout << std::endl;
}
}
Here is the output:
$ ./a.out
input width
10
input height
7
input character
*
OUTPUT
**********
* *
* *
* *
* *
* *
**********
Add an if to the cout << character line. If we're not in the first row or column, output a space instead of the character.