I was working though some beginning problem sets with Harvard's online CS50 class. I got the problem to work correctly but I was wondering if there would possibly be a cleaner or better way to get the program to work.
The goal of the program is to print a right-aligned pyramid comprised of hash-tags and space characters. Any guidance in regards to style or tricks would be very welcome.
/* Creating the mario program, whose goal is to create a
* pyramid by accepting input from the user to get the
* height then aligning the pyrimid to the right.
*
*/
#include <stdio.h>
#include <cs50.h>
int main(void)
{
// get user input and set to variable
printf("Height: ");
int height = GetInt();
int i, j, k;
for(i = 1 ; i < height; i++)
{
// create n-1 spaces
for(k = (height - 2); k > (i-1); k--)
{
printf("%c", ' ');
}
// create n+1 hash tags
for(j = 0; j < (i+1); j++)
{
printf("#");
}
printf("\n");
}
return 0;
}
I'm assuming by cleaner you mean "spiffy and fancyer".
This looks spiffy to me:
#include <stdio.h>
#include <cs50.h>
int main(void) {
// get user input and set to variable
printf("Height: ");
int height = GetInt();
int hm2 = height - 2;
int j, k;
for(int i = 1 ; i < height; i++) {
// create n-1 spaces
for(k = hm2; k > (i-1); k--)
printf("%c", ' ');
// create n+1 hash tags
for(j = 0; j < (i+1); j++)
printf("#");
printf("\n");
}
return 0;
}
However, don't get too caught up in making your code fancy. Although it's nice if you're working with others, or yourself really. Your example looked fine.
Now, optimization-wise, that's something to worry about. Just remember that too much optimization can potentially break your program.
For everyone's consideration: this is what "all style and no readability" looks like :)
i = 0;
while (i++ < height*height)
printf ("%c%s", (i-1)/height < height-(i-1)%height-1 ? ' ' : '#',
i % height ? "" : "\n");
It is nigh on impossible to see what the code does without running it. If there is to be a follow-up exercise, this is hard to re-write to form, say, an even-sided pyramid. I'd probably throw this away and start again with the basics, before concatenating it again into a little monster such as this.
(later) Ever so slightly more neat to put the i++ at the end, so two times (i-1) gets traded for a slightly more complicated end-of-line test:
i = 0;
do
printf ("%c%s", i/height < height-i%height-1 ? ' ' : '#',
i % height==height-1 ? "\n" : "");
while (++i < height*height);
I think by cleaner and better way you mean to be a perfect shaped right angled triangle pyramid.
For this you should do as
Change
printf("Height: ");
to
printf("Height: \n\n");
and
for(i = 1 ; i < height; i++)
to
for(i = 0 ; i < height; i++)
And see the sample output.
Here's a suggestion:
#include <stdio.h>
#include <cs50.h>
int main(void) {
//initialize variables
int height, hm2, j, k, i;
printf("Height: \n");
// Get user input
height = GetInt();
hm2 = height - 1;
for(i = 0; i < height; i++) {
// create n spaces
for(k = hm2; k > i; k--)
printf("%c", ' ');
// create n+1 hash tags
for(j = 0; j < i+1; j++)
printf("#");
printf("\n");
}
return 0;
}
Result if the user entered a 5 for the height:
Height:
#
##
###
####
#####
A couple things I considered with this version of the code:
-In C, it's good practice to declare all variables separately from giving them a value and assign values later. Some compilers may bring up this error if you to declare and assign a value in a for loop: "error: ‘for’ loop initial declarations are only allowed in C99 mode". These changes are considered with what I have provided.
//initialize variables
int height, hm2, j, k, i;
-I added a newline here
printf("Height: \n");
-Instead of hm2 = height - 2 I changed it to:
hm2 = height - 1;
-First loop, now we give i a value and set it to 0 to meet the other changes that were made:
for(i = 0; i < height; i++) {
-For the loop creating n spaces I changed it to:
for(k = hm2; k > i; k--)
-Finally removed parenthesis (no need in this case) in last for loop:
for(j = 0; j < i+1; j++)
Cheers
Related
in the cs50 project, we have to make a Mario hash pyramid then right align it to the left and I'm having a pretty hard time doing it and I hope someone could give me some advice
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int h = 0;
int l = 0;
int c = 0;
do {
h = get_int("Height: ");
} while (h > 8 || h < 1);
{
for (int w = 0; w < h; w++)
{
for (int j = -1; j < w; j++)
{
printf("#");
}
printf("\n");
}
}
}
output:
what is needed:
try to make two-loop one for the empty space you can also use - and second for #..
after the align become to left del the -
Before checking the code that I'll provide, I strongly advise you to do hard coding for every single line of pyramide. This is the only way you will see and understand the design pattern of the following algorithm. Then, feel free to check the following code snippet.
Here is the code that builds pyramid right-aligned.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height = 0;
do
{
height = get_int("Please enter a height between 1 and 8 (inclusive)\nHeight: ");
}
while (height > 8 || height < 1);
for(int i = 0; i < height; i++)
{
for(int j = height - i; j > 1; j--)
{
printf(" "); // print empty spaces.
}
for(int k = 0; k <= i; k++)
{
printf("#"); // print hashes.
}
printf("\n"); // go to next line.
}
}
I am working on this problem from the CS50 class. I am still a beginner. What I need to program is this:
Toward the end of World 1-1 in Nintendo’s Super Mario Brothers, Mario
must ascend right-aligned pyramid of blocks, a la the below.
screenshot of Mario jumping up a right-aligned pyramid
Let’s recreate that pyramid in C, albeit in text, using hashes (#) for
bricks, a la the below. Each hash is a bit taller than it is wide, so
the pyramid itself is also be taller than it is wide.
#
##
###
####
#####
######
#######
########
The program we’ll write will be called mario. And let’s allow the user
to decide just how tall the pyramid should be by first prompting them
for a positive integer between, say, 1 and 8, inclusive.
However I have tried many ways, two of which are these:
code mariov1
After looking at some Stack Overflow attempts, it now looks like this:
#include <cs50.h>
#include <stdio.h>
string hash(int);
int main(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n < 0 || n > 8);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n-1-i; j++)
{
for(int j = 0; j < i+1; j++)
{
printf(".");
}
printf("#");
}
printf("\n");
}
}
What can I try next?
Suriyu, to add to what Weather Vane said. To pass it through Check50, you'll still need to make small tweaks to the code so that it passes through all CS50 tests.
For the do-while loop, n <=0 instead of n < 0 to ask for an input when n = 0, because the specification demands a minimum of one brick (1 to 8 both inclusive).
You need only the two loops, don't print extra characters not specified in the problem set, ex: printf(".");
All the best with CS50, it's going to be a fun experience!
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Height: ");
}
while (n < 1 || n > 8);
// this for loop makes new lines
for (int i = 0; i < n; i++)
{
// here I have two for loops nested inside the above for loop,
// I previously made the mistake of having two inner loops nested.
// this 2nd for loop prints n-1-i spaces
// because if n=5, then in the 4th row, there will be 5-1-3 spaces/dots
for (int j = 0; j < n - 1 - i; j++)
{
printf(" ");
}
// this 3rd for loop prints i+1 hashes
// because if n=5, then in the 4th row, there will be 3+1 hashes.
// (3 because you count from 0)
for (int j = 0; j < i + 1; j++)
{
printf("#");
}
printf("\n");
}
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Height of the pyramid is:\n");
}
while (n < 1 || n > 8); //condition to get a number from 1-8 from the user
for (int i = 0; i < n; i++) //loop for height
{
for (int j = 0; j < n - 1 - i; j++) //loop for spaces on left pyramid
{
printf(" ");
}
for (int k = 0; k < i + 1; k++) // loop for hashes on left pyramid
{
printf("#");
}
printf(" "); // spacing between pyramids
for (int p = 0; p <= i; p++) //loop for right pyramid
{
printf("#");
}
printf("\n");
}
}
This is the advanced version of the problem if you decide to try it.
Here's a different approach. Instead of iteratively printing blanks, followed by iteratively printing number signs, this version creates a buffer (size defined by a precompiler constant - currently set to 8, change it if you want to allow bigger pyramids), then for each row in the pyramid it first fills the buffer with number signs, then overlays the beginning of the line with the proper number of spaces, and then prints it:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define MAXSIZE 8
int main(void)
{
int size, spaces;
char buf[MAXSIZE+1];
do
size = get_int("Height: ");
while (size < 0 || size > MAXSIZE);
buf[size] = '\0';
for(spaces = size-1 ; spaces >= 0 ; --spaces)
printf("%s\n", (char *)memset(memset(buf, '#', size), ' ', spaces));
}
EDIT
And here's yet another approach which builds the entire output block in an array in memory and then prints it using a single call to puts:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#define MAXSIZE 8
#define TOTSIZE ((MAXSIZE+1) * MAXSIZE)
int main(void)
{
int size, spaces;
char buf[TOTSIZE+1];
do
size = get_int("Height: ");
while (size < 0 || size > MAXSIZE);
memset(buf, '\n', (size+1)*size);
buf[((size+1)*size)] = '\0';
for(char *p = buf, spaces = size-1 ; *p != '\0' ; p += size+1, --spaces)
memset(memset(p, '#', size), ' ', spaces);
puts(buf);
}
This is an option that likely works best:
from cs50 import get_int
while True:
n=get_int("Enter Height: ")
if n>=1 and n<=8:
break
for i in range(0, n-1):
print(" " * (n - (i+1)) + "#" * (i+1))
I thought long and hard before asking this in here but I've spent too much time now trying to figure this one out without cheating.
The CS50 mario ps1 (less comfortable) asks for a *simple left align (at first) pyramid, but my code is giving me it upside down and I can't figure why.
#include <cs50.h>
#include <stdio.h>
int main (void)
{
int n;
do
{
n = get_int("Pyramid Height: ");
}
while (n < 1 || n > 8);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i ; j++)
printf("#");
for (int j = 0; j < n - i; j++)
{
printf(" ");
}
printf("\n");
}
}
I'm sorry if this type of questioning shows up regularly here but I really do need your help.
Thanks in advance.
edit:
expected result:
........#
.......##
......###
.....####
....#####
...######
..#######
.########
I can change the dots to spaces afterwards, this is just for visualisation;
the restriction for height is 8, so I guess that each line has always eight characters;
I actually added trailing spaces so that the pyramid could be right aligned, I've metioned wrong before;
I'm going to check the How to debug small programs?;
Sorry, I'm new to this, I didn't know there was a difference between here and stack exchange, gonna look into that.
*Sorry for the "meh" english, it is not my native language.
See what is the difference between my and your code (especially how to count):
void draw(int n, int align, int dir)
{
for (int i = 1; i <= n; i++)
{
if(align)
{
for(int s = 0; s < (dir ? (n - i) : i - 1); s++)
{
printf(" ");
}
}
for (int j = 0; j < (dir ? i : (n - i + 1)) ; j++)
{
printf("#");
}
printf("\n");
}
}
int main (void)
{
draw(8,1,0);
printf("\n");
draw(8,1,1);
printf("\n");
draw(8,0,0);
printf("\n");
draw(8,0,1);
}
https://godbolt.org/z/7YT16j
my code is giving me it upside down and I can't figure why
Let's see what the code looks like
// There's a loop executed n times. The body prints a line, so n lines are printed.
// In case you have doubts, the characters are normally printed top to bottom and
// left to right.
for (int i = 0; i < n; i++)
{
// The following loop prints (n - i) characters '#' at the beginning
// of each line. That's NOT what you are supposed to do, kind the opposite.
for (int j = 0; j < n - i ; j++)
printf("#");
// You should first print the spaces, then the '#'s, starting from 1 '#' at
// the first line and increasing the number by one at each line (so you have
// to change the condition in the loop accordingly).
// This loop prints the right amount of spaces, but only after
// all the '#'s and just before the end of the line, so that you just
// can't see them (change the printed char to '.' to visualize those).
for (int j = 0; j < n - i; j++)
{
printf(" ");
}
// Note that you could use putchar('\n'), here and previously, to print
// only one char, instead of using printf() to print string literals.
printf("\n");
}
I turned in my assignment to my online C programming class and was docked huge due to the fact that my program was "hard coded, and I can't see how it would be considered "hard coded" as I ask for user input. The following was my code:
#include <stdio.h>
#include <stdlib.h>
#define IMAX 3
#define JMAX 4
int main()
{
float a[IMAX][JMAX];
float avgrow[5];
float avgcol[5];
int i,j;
char c;
printf ("This program will allow you to enter numbers for 3 rows and 4 columns from left to right then filling down, and take the averages of the rows and columns and list them next to the row and under the columns. You may use decimals but only 2 will display in the results. Press enter!\n");
scanf ("%c",&c);
printf("Enter 12 numbers here for your rows and columns:\n");
for(i = 0; i < IMAX; i++)
{
for(j = 0; j < JMAX; j++)
{
scanf("%f",&a[i][j]);
}
}
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}
printf(" Column1 Column2 Column3 Column4 Row Average\n\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[0][0],a[0][1],a[0][2],a[0][3],avgrow[0]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[1][0],a[1][1],a[1][2],a[1][3],avgrow[1]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[2][0],a[2][1],a[2][2],a[2][3],avgrow[2]);
printf("\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t\n",avgcol[0],avgcol[1],avgcol[2],avgcol[3]);
return 0;
}
All it was supposed to do was make a 2-d array with 3 rows and 4 columns, then take the average of the rows and display that next to to the row in a table. Than take the average of the columns and display them beneath the columns in the table.
This was his comments on my assignment "Well, you got the correct answers, but when dealing with a 2-D array, you should use nested for loops. Not one for loop and then a lot of "hard coding" values into the program."
Any help deciphering this would be appreciated as I though I was finally understanding programming until this.
First of all it's not meaningful to talk about a program being hard coded or not. Rather one would talk about specific values being hard coded. What this means is that you wrote their values directly into the code rather than putting them in a constant or variable that can easily be changed.
In this case the values you hard-coded are the number of rows and the number of columns. You do have constants for these, but you don't use them consistently. That is if you changed your constants to turn the array into a 5x5 array, your code would now break because parts of the code would still act like it is an 3x4 array.
Specifically there are two loops in your code where you're accessing the indices [0][0] through [2][3] by spelling out each index in that range specifically rather than using a loop. This means that if you change IMAX and JMAX, it will still use those same indices, which aren't correct any more.
So your array indices are hard-coded and changing the array dimensions breaks your program.
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}
Notice the copying/pasting of nearly identical code? That's often a sign of hardcoding -- the presence of constants in the code's text or structure. How do you change the 3 and the 4? They're "hard" -- built into the code.
The proof it's a problem -- you have:
#define IMAX 3
#define JMAX 4
But if you actually change those, the code will break. Look at this line of code:
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
That's an average if, and only if, JMAX is 4. The code was build with the understanding that JMAX had to be 4 -- JMAX was "hard coded" to 4.
Looking at the following code:
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
This code assumes that a always has 3 rows and 4 columns, regardless of how a was actually declared. If you changed JMAX to 2, for example, then your code above would break because a would have dimension 3x2, and you'd be attempting to access elements outside of the array bounds.
What your instructor was looking for was something along these lines:
for(j = 0; j < JMAX; j++)
{
float sum = 0.0;
for (i = 0; i < IMAX; i++ )
{
sum += a[i][j];
}
avgrow[j] = sum/JMAX;
}
This code makes no assumptions about the dimensions of a beyond what is specified by IMAX and JMAX.
Note also that your declarations for avgrow and avgcol are hard-coded to 5, when they should also be based on IMAX and JMAX:
float avgrow[IMAX];
float avgcol[JMAX];
float avgrow[5];
float avgcol[5];
for(j = 0; j < JMAX; j++)
{
avgrow[0] = (a[0][0]+a[0][1]+a[0][2]+a[0][3])/JMAX;
avgrow[1] = (a[1][0]+a[1][1]+a[1][2]+a[1][3])/JMAX;
avgrow[2] = (a[2][0]+a[2][1]+a[2][2]+a[2][3])/JMAX;
}
for(i=0; i < IMAX; i++)
{
avgcol[0] = (a[0][0]+a[1][0]+a[2][0])/IMAX;
avgcol[1] = (a[0][1]+a[1][1]+a[2][1])/IMAX;
avgcol[2] = (a[0][2]+a[1][2]+a[2][2])/IMAX;
avgcol[3] = (a[0][3]+a[1][3]+a[2][3])/IMAX;
}
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[0][0],a[0][1],a[0][2],a[0][3],avgrow[0]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[1][0],a[1][1],a[1][2],a[1][3],avgrow[1]);
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n",a[2][0],a[2][1],a[2][2],a[2][3],avgrow[2]);
printf("\n");
printf("%8.2f\t%8.2f\t%8.2f\t%8.2f\t\n",avgcol[0],avgcol[1],avgcol[2],avgcol[3]);
THESE ALL STEPS YOU HAVE TAKEN ARE HARD CODING AS YOU ARE SPECIFICALLY MENTIONING THE INDICES IF SUPOSE the value imax and jmax changes then you have to manually change/add avgcol[index] in taking averages as well as in output...
Your programm should be independent of it it should only depend on the value of i max and jamx
for a reference you can view a sample of your code in which i have removed hardcoding
http://ideone.com/mXymKS
Although this code could be simplied to a great extent...
You have used explicit integer values for the array indices of avgrow and avgcol. To avoid hard-coding, try using a loop with an integer variable as index, e.g.,
for(int k=0; k<4; ++k)
and then assign values to avgrow[k].
Your professor expected you to be able to modify the number of line and columns in your program easily. The disadvantage of the program you wrote is that a modification of one of those two parameters require you to change the whole program. You can achieve more flexibility for instance like this:
#include <stdio.h>
#include <stdlib.h>
#define IMAX 3
#define JMAX 4
int main()
{
float a[IMAX][JMAX];
float avgrow[IMAX] = {0};
float avgcol[JMAX] = {0};
printf ("This program will allow you to enter numbers for %d rows"
"and %d columns from left to right then filling down, and"
" take the averages of the rows and columns and list them"
" next to the row and under the columns. You may use "
"decimals but only 2 will display in the results. Press"
" enter!\n", IMAX, JMAX);
char c;
scanf ("%c",&c);
printf("Enter %d numbers here for your rows and columns:\n", IMAX * JMAX);
for(int i = 0; i < IMAX; i++) {
for(int j = 0; j < JMAX; j++) {
scanf("%f",&a[i][j]);
}
}
for(int i = 0; i < IMAX; i++) {
for(int j = 0; j < JMAX; j++) {
avgrow[i] += a[i][j];
}
avgrow[i] /= JMAX;
}
for(int j = 0; j < JMAX; j++) {
for(int i = 0; i < IMAX; i++) {
avgcol[j] += a[i][j];
}
avgcol[j] /= IMAX;
}
for(int i = 0; i < IMAX; i++) {
printf("Column%d\t", i);
}
printf("Row-Average\n\n");
for(int j = 0; j < JMAX; j++) {
for (int i = 0; i < IMAX; i++) {
printf("%8.2f\t", a[i][j]);
}
printf("%8.2f\n", avgrow[j]);
}
for(int i = 0; i < IMAX; i++) {
printf("%8.2f\t", avgcol[i]);
}
return 0;
}
In addition to the rich answers already exist, I'd like to point out something about acquiring data and computing averages without much repetitions :
So define your average arrays like this :
float avgrow[IMAX] ={0};
float avgcol[JMAX] ={0};
Then in the same loop where you scanf user's entries you can simultaneously compute averages like this:
printf("Enter %d numbers here for your rows and columns:\n", IMAX*JMAX);
for(i = 0; i < IMAX; i++)
{
for(j = 0; j < JMAX; j++)
{
scanf("%f",&a[i][j]);
avgrow[i] += a[i][j]/JMAX;
avgcol[j] += a[i][j]/IMAX;
}
}
Next step is just to print out everything, and let it be automated too :)
for(i=1; i<= JMAX; i++) printf("Column%d\t\t", i);
printf("Row Average\n");
for(i=0; i<IMAX; i++)
{
for(j=0; j<JMAX; j++)
{
printf("%8.2f\t", a[i][j]);
}
printf("%8.2f\n", avgrow[i]);
}
for(i=0; i<JMAX; i++)
printf("%8.2f\t", avgcol[i]);
By the END
you have a code that computes row and col averages for any sizes. i.e. try changing IMAX or JMAX
Code1:
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 2; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k; j++)
printf("%hu ", j);
putchar('\n');
}
return 0;
}
Output of Code1:
0 1 2 3
4 5 6 7
Remarks of Code1:
Space after 3 and 7
Newline after 7 (Stackoverflow has removed it)
Code2:
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 2; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k; j++)
{
printf("%hu", j);
if (j + 1 != k) putchar(' ');
}
if (i + 1 != 2) putchar('\n');
}
return 0;
}
Output of Code2:
0 1 2 3
4 5 6 7
Remarks of Code2:
No space after 3 and 7
No newline after 7
Additional remark of Code2:
The problem of Code2 is that the algorithm always compares two values in the if blocks and so Code2 is not efficient. I want to use Code1 and change these:
Code3
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 2; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k; j++)
printf("%hu ", j);
printf("\b\n");
}
putchar('\b');
return 0;
}
These do not show the same output of Code2 because \b does not erase anything.
My question:
Is there any standard way to do so what I've tried in Code3?
Remark of my question:
I have searched the internet but have not determined the solution.
Edit the question if it is not clear.
Edit: I don't know why my question is not useful or constructive. Though the above is an arbitrary small example, but performance might be an issue when processing very large amount of data. I thought that the way of removing character from console output might improve performance and there might be a specific way to do so. That's why I've asked the question. I could write the following codes in the answers. Now I've known via comments that removing character from console output is not possible because it is implementation dependent.
The usual approach to this is to treat either the first or the last printf as a special case (outside of the loop):
for(ii=0; ii<2; ii++) {
jj = 0;
printf("%d", jj); // first number printed without space.
for(jj=1; jj<4; jj++) {
printf(" %d", jj); // include the space before the number printed
}
if(ii<2-1) printf("\n");
}
Obviously I simplified how the loops are constructed and what is printed - for simplicity. You could make the first printf statement
printf("\n%d", jj);
then you have a newline at the start of your output (often a good thing) and then you don't need the if statement later - you just don't have a newline printed at the end of the line (because it will be printed at the start...)
There are marginally more efficient ways of doing this that would involve no if statements at all - but these all come at the expense of less readable code. For example, here is a "no loop unrolling and no additional if statements" version of the code:
http://codepad.org/01qPPtee
#include <stdio.h>
int main(void) {
int ii, jj;
ii = 0;
while(1) {
jj = 0;
while(1) {
printf("%d", jj); // include the space before the number printed
jj++;
if(jj<4) printf("."); else break;
}
ii++;
if(ii<2) printf("*\n"); else break;
}
return 0;
}
Output:
0.1.2.3*
0.1.2.3
Basically I have taken the functionality of the for loop and made it explicit; I also use a . rather than a and "*\n" rather than "\n" to show in the printout that things behave as expected.
It does what you asked without extra evaluation of the condition. Is it more readable? Not really...
If it really bothers you, you can unroll your loops a little so that you treat the last item as a special case:
#include<stdio.h>
int main()
{
unsigned short i, j, k;
for (i = 0; i < 1; i++)
{
k = i * 4 + 4;
for (j = k - 4; j < k - 1; j++)
{
printf("%hu ", j);
}
printf("%hu\n", j);
}
k = i * 4 + 4;
for (j = k - 4; j < k - 1; j++)
{
printf("%hu ", j);
}
printf("%hu", j);
return 0;
}
#include <stdio.h>
int main(){
unsigned short num = 0, to=8;
while(num < to){
printf("%hu", num++);
if(num < to)
putchar(num % 4 == 0 ? '\n' : ' ');
}
#if 0
do{
printf("%hu", num++);
}while(num < to && putchar(num % 4 == 0 ? '\n' : ' '));
#endif
return 0 ;
}
Well, to try to answer your question, here's how I would do it:
for (i = k = 0; i < 2; i++){
if (i > 0) printf("\n");
for (j = 0; j < 4; j++, k++){
if (j > 0) printf(" ");
printf("%d", k);
}
}
I do it this way because I want to be sure every line but the first starts with a \n, and every item is separated by a space from the one before it.
Also, I do not want the row and column position to be intimately tied to the content of what is being printed.
In terms of performance, keep in mind that these if statements cost about 1 cycle, while each character printed costs at least hundreds if not thousands. printf goes through many layers of system calls to interpret its format string, build a buffer, send the buffer to the system I/O routines, which then cause repainting and scrolling of the console window. Get the idea?
DO NOT WORRY about performance unless you know you have a problem.
Then, don't guess. Use a diagnostic. Here's what I do.