Home > database >  How can I reduce the number of blocks with for-loops?
How can I reduce the number of blocks with for-loops?

Time:09-22

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;
}
  • Related