Reputation: 41
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
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
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