I am grinding away at a simple for-loop exercise where the user can enter a width and a height, and the program prints out a square with stars and spaces, like this:
Enter width and height: 8 4
********
* *
* *
********
and I have made a solution, but it just feels like I could redsuce the number of blocks with loops some... Can somebody help me with this? Here is the code:
#include <stdio.h>
int main(void)
{
int width, height;
printf("Enter width and height: ");
scanf("%d %d", &width, &height);
for(int i = 0; i < 1; i )
{
for (int j = 0; j < width; j )
{
printf("*");
}
printf("\n");
}
for(int i = 0; i < height - 2; i )
{
printf("*");
for (int j = 0; j < width -2; j )
{
printf(" ");
}
printf("*\n");
}
for(int i = 0; i < 1; i )
{
for (int j = 0; j < width; j )
{
printf("*");
}
printf("\n");
}
}
Thank you in advance!
CodePudding user response:
One way could be:
int main(void)
{
int width = 8;
int height = 4;
for (int h = 0; h < height; h)
{
for (int w = 0; w < width; w)
{
if (w == 0 || h == 0 || h == (height-1) || w == (width-1))
{
putchar('*');
}
else
{
putchar(' ');
}
}
putchar('\n');
}
return 0;
}
That said... IMO this isn't really better than your approach. The use of 3 simple "loop-blocks" makes it very easy to see what your code is doing. This approach with a single "loop-block" and an if
statement is a bit harder to read.
So I would say...
You approach/code is fine if you just delete the lines
for(int i = 0; i < 1; i )
as they do absolutely nothing.
And use putchar
instead of printf
for printing a single character.
Then your approach is pretty okay. If you want to avoid the first and last loop-block to be the same (i.e. avoid repeating the same code), you could put the code into a function.
CodePudding user response:
I packaged some loop lines into function. Here is the code:
#include <stdio.h>
void PrintCharLine(char c, int width){
for (int j = 0; j < width; j ){
putchar(c);
}
}
void PrintEdge(int width){
PrintCharLine('*', width);
printf("\n");
}
void PrintBody(int width, int height){
for(int i = 0; i < height - 2; i )
{
printf("*");
PrintCharLine(' ', width -2);
printf("*\n");
}
}
int main(void)
{
int width, height;
printf("Enter width and height: ");
scanf("%d %d", &width, &height);
PrintEdge(width);
PrintBody(width, height);
PrintEdge(width);
}
as @Support Ukraine said, you can replace PrintCharLine with printf("%.*s for less for loop. but the width range has some limit.
CodePudding user response:
Here's another variation. Factor out "common" code into a "helper function"
#include <stdio.h>
void row( int wid, int fill ) {
wid -= 2;
putchar( '*' );
while( wid-- )
putchar( fill ? '*' : ' ' );
putchar( '*' );
putchar( '\n' );
}
int main() {
int width, height;
printf( "Enter width and height: " );
if( scanf( "%d%d", &width, &height ) != 2 ) {
fprintf( stderr, "scanf() failure\n" );
return 1;
}
row( width, 1 );
for( int i = 1; i < height - 1; i )
row( width, 0 );
row( width, 1 );
return 0;
}
And when you've done that, you begin to notice even more economies that make a "helper function" so trivial its code is returned to the calling location...
int main() {
int width, height;
printf( "Enter width and height: " );
if( scanf( "%d%d", &width, &height ) != 2 ) {
fprintf( stderr, "scanf() failure\n" );
exit( 1 );
}
for( int i = 0; i < height; i ) {
int wid = width - 2;
int fill =
#ifdef PEDESTRIAN
(i == 0 || i == height-1) ? '*' : ' ';
#else
" *"[!(i%(height-1))];
#endif
putchar( '*' );
while( wid-- ) putchar( fill );
puts( "*" );
}
return 0;
}