Adam Heffernan-Munro
Adam Heffernan-Munro

Reputation: 41

Printing a max of 50 Chars on a line, printing a new line of chars if the argument is say 55

I'm looking to draw a line of char's if the argument is less than 0 must print 50 chars on the line. If argument is over 50, must print first 50 chars, new line then continue to print the chars until argument becomes 0. When the argument is over 50 I don't know how to print the first 50 chars on one line, then the remaining chars on a new line

void drawLine(char c, int n){
    if(n<0){
        for(int i =0; i < 50; i++){
            printf("%c",c);
        }
    }
    else if(n>50){
        for(int i=0; i<50;i++){
            printf("%c",c);
            n--;
            if (n!=0 && i % 50 == 0){
                printf("\n");
                for(int i= 0; i<50;i++){
                    printf("%c",c);

                }
                break;
            } 

        }

    }
    else{
        for(int i=0;i<n;i++){
            printf("%c",c);
        }
    }
    printf("\n\n");
}

int main(void) {
    drawLine('*',55);
    return 0;
}

Upvotes: 1

Views: 681

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84579

You can greatly simplify your logic just by thinking about the problem a little differently.

First, never use the variadic printf function to output a single character -- that is the wrong tool for the job. Instead use putchar() or fputc which are character-oriented output functions. [1]

When working with void functions, there is no reason you cannot return from any point within the function. You can use this to your advantage to avoid nesting if{} else{}... Simply return after you complete the needed block of code.

Next, don't use magic numbers throughout your code. If you need a constant for 50, then #define one, e.g.

#define LNSZ 50

That way if you decide to make your line size 60, there is only one place, easily accessible, at the top of your code where you can make the change. No need to go picking though multiple for loop declarations to change each loop limit.

Putting those pieces together, you can rewrite your drawline function as follows (note: traditionally C avoid the use of camelCase function names)

void drawline (char c, int n)
{
    if (n < 0) {                        /* handle value < 0  */
        for (int i = 0; i < LNSZ; i++)  /* output LNSZ chars */
            putchar (c);
        putchar ('\n');                 /* tidy up with '\n' */
        return;                         /* all done          */
    }

    for (int i = 0; i < n; i++) {       /* output n chars    */
        if (i && i % LNSZ == 0)         /* after every 50 \n */
            putchar ('\n');
        putchar (c);                    /* output char       */
    }
    putchar ('\n');                     /* tidy up with '\n' */
}

Putting together a short example to exercise the function by allowing the line size to be specified as a command line argument (and using a default of 55 if no argument is given), you could do something similar to the following:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

#define LNSZ 50

void drawline (char c, int n)
{
    if (n < 0) {                        /* handle value < 0  */
        for (int i = 0; i < LNSZ; i++)  /* output LNSZ chars */
            putchar (c);
        putchar ('\n');                 /* tidy up with '\n' */
        return;                         /* all done          */
    }

    for (int i = 0; i < n; i++) {       /* output n chars    */
        if (i && i % LNSZ == 0)         /* after every 50 \n */
            putchar ('\n');
        putchar (c);                    /* output char       */
    }
    putchar ('\n');                     /* tidy up with '\n' */
}

int main (int argc, char **argv) {

    errno = 0;
    long v = argc > 1 ? strtol (argv[1], NULL, 10) : 55;

    if (errno) {    /* minimal validation of any strtol conversion */
        perror ("invalid conversion");
        return 1;
    }

    if (v < INT_MIN || INT_MAX < v) {   /* validate v in int range */
        fprintf (stderr, "error: value exceeds storable int.\n");
        return 1;
    }

    drawline ('*', (int)v);

    return 0;
}

Example Use/Output

$ ./bin/drawline
**************************************************
*****

$ ./bin/drawline 50
**************************************************

$ ./bin/drawline -1
**************************************************

$ ./bin/drawline 10
**********

$ ./bin/drawline 151
**************************************************
**************************************************
**************************************************
*

Look things over than let me know if you have any further questions.

footnote [1] Yes, a smart compiler may optimize printf to putchar for you, but do not rely on the compiler to fix lazy coding habits.

Upvotes: 0

Emma X
Emma X

Reputation: 277

I tried to keep as much of your original code as possible whilst making the code clearer and better readable. The problem for n greater than 50 was that if (n != 0 && i % 50 == 0) is always true for the first iteration with n something above 50 and i = 0, since 0 % 50 = 0. Therefore it only printed one instead of 50 elements on the first line.

void drawLine (char c, int n) {
    //n less than zero equals n = 50
    if (n < 0) {n = 50;}

    //if printable on first line
    if (n <= 50) {
        for (int i = 0; i < n; i++) {
            printf("%c",c);
        }
    }

    else {
        //print 50 chars on first line
        for (int i = 0; i < 50; i++) {
            printf("%c",c);
        }
        //reduce n by this number
        n = n - 50;
        printf("\n");

        //print remaining number of chars
        for (int i = 0; i < n; i++) {
            printf("%c",c);
        }
    }

    printf("\n\n");
}

If you want to begin a new line for every 50 elements, a loop starting a new line every 50 iterations is the way to go.

Upvotes: 1

Related Questions