Code printing correct output too many times (CS50)

I am very new to coding and learning via Harvard’s free CS50 course. Problem set 1 has been difficult, and I think I’m making it more challenging by doing things the hard way, ie I am trying to create functions for my code to get acclimated to how creating functions works. The task is to make a left-aligned pyramid with a height between 1 and 8. I’ve created functions to get the height from the user and to print the pyramid. The issue is with how the pyramid is printing. It prints correctly, but too many times. So, if the user types ‘3’ when prompted for the height, it should print this:

  #
 ##
###

Instead, it prints that exact pyramid three times:

  #
 ##
###
  #
 ##
###
  #
 ##
###

What would the solution be to fix this based on my below code?

main:

{
    int n = get_height();

    for (int j = 0; j < n; j++)
    {
        for (int i = 0; i < n; i++)
        {
            print_row(n - i - 1, i + 1);
        }
    }
}

functions:

int get_height(void)
{
    int n;
    do
    {
        n = get_int("Height: ");
    }
    while (n < 1 || n > 8);
    return n;
}

void print_row(int spaces, int bricks)
{
    // Print spaces
    for (int j = 0; j < spaces; j++)
    {
        printf(" ");
    }
    // Print bricks
    for (int i = 0; i < bricks; i++)
    {
        printf("#");
    }
    printf("n");
}

1

for (int j = 0; j < n; j++)
    {
        for (int i = 0; i < n; i++)
        {
            print_row(n - i - 1, i + 1);
        }
    }

What the code is doing:

  • print_row() prints one single row.
  • The inner loop prints n rows. Or generates one pyramid.
  • The outer loop executes n times. So the outer loop is generating n pyramids (as the inner loop generates a single pyramid, n * 1 pyramid is equal to n pyramids ).

That’s how your code is printing the pyramid n times. Because after generating the pyramid once, you repeat the process until you’ve generated n pyramids.

Simply remove the outer loop.

1

OP: “to get acclimated to how creating functions works

Other answers have correctly diagnosed the problem as too many loops in main().

Since you are learning, here is a version that destructively decrements counters demonstrating slightly less code (less chance for a bug to hide somewhere.)

// #includes as required

// get_height() as per OP's code

void print_row( int spaces, int bricks ) {
    /* A comment to say, "Have removed this comment; its being only 'noise' */
    while( spaces-- )
        printf( " " ); // putchar( ' ' ); would work as well /* tutorial */

    while( bricks-- )
        printf( "#" );

    printf( "n" );
}

int main( void ) {
    int n = get_height();
    int b = 0;

    while( n )
       print_row( --n, ++b ); // fewer spaces and more bricks each time

    return 0;
}

Each time print_row() is called, it receives a fresh pair of values for its use.


This code still uses the non-descript variable n in main(). A better name could be chosen.

Be wary of using i and j together in code.

Their similar appearance makes tracking down invisible bugs almost impossible at 4AM.
arr[i][j] & arr[j][i] look too similar in a small font or viewed with bleary eyes.
Plus, i and j are so generic they provide little information to a source code reader.


Comments like // Print spaces are considered noise.

Comments should explain why code has been written as it has:

// going left-then-right because right-then-left always fails on Thursdays

Don’t explain the simple stuff. Let your code speak for itself.

x = x + 1; // increment x is excrement

Use comments sparingly and only to explain the “why” of code.


Advanced technique:
Acknowledging that the CS50 challenge is to print rows of spaces (SP) and hashes ('#'), here is a possible replacement for print_row() that almost fulfills the requirements.
(Offered as an example of the power of C’s function printf().)

void print_row( int spaces, int bricks ) {
    printf( "%*c%0*dn", spaces+1, ' ', bricks, 0 );
}

Its output when int n = 5; is used in main():

     0 // <== definitely not a '#'
    00
   000
  0000
 00000

printf() is commonly used to pad its output with leading or trailing SP characters to achieve a desired width.
Not commonly used, printf() is also capable of producing multiple instances of the digit 0. In this example, the value 0 has been printed with increasing numbers of leading 0‘s. To the best of my knowledge, SP and 0 are the only characters that can be coaxed out of printf()‘s capabilities for “padding” output.

This is something quite esoteric to store away, and come back to once you’ve learned much more about C and printf(). Its terseness, and especially its opacity, WOULD justify (require!?) a comment that explains to the casual reader what is going on with that one line of code.

4

Your code is incomplete, but it seems the problem is here.

    for (int j = 0; j < n; j++)
    {
        for (int i = 0; i < n; i++)
        {
            print_row(n - i - 1, i + 1);
        }
    }

The inner loop prints the rows. The outer loop repeats the process. A giveaway is that j is never used. If n is 3 you’ll get 3 rows repeated 3 times.

Adding printf("i: %d, j: %dn", i, j) to show the value of i and j at each print_row call will be illustrative.

    for (int j = 0; j < n; j++)
    {
        for (int i = 0; i < n; i++)
        {
            printf("i: %d, j: %dn", i, j);
            print_row(n - i - 1, i + 1);
        }
    }

4

As others have identified the core issues with your loops, it may be instructive to see how we can remove some of these loops.

void print_row(int spaces, int bricks)
{
    // Print spaces
    for (int j = 0; j < spaces; j++)
    {
        printf(" ");
    }
    // Print bricks
    for (int i = 0; i < bricks; i++)
    {
        printf("#");
    }
    printf("n");
}

Let’s use printf to print the spaces for us by including a width field.

void print_row(int spaces, int bricks) {
    printf("%*s", spaces, "");

    for (int i = 0; i < bricks; i++) {
        printf("#");
    }

    printf("n");
}

But apparently the longest line is 8 characters and printf‘s %s specifier can limit the length of a string printed. We only need to be able to print eight bricks.

void print_row(int spaces, int bricks) {
    char *bricks_str = "########";
    int line_len = spaces + bricks;

    printf(
        "%*.*sn", 
        line_len,   // The amount of chars to pad the string to.
        bricks,     // The maximum number of characters to print
                    // from the string.
        bricks_str
    );
}

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật