I am doing printf("\t%d", i) in a for-loop to print column labels for a table.
Before the loop, I do printf("some string ===>").
An issue I notice is that for example, if I do printf("some string===>" (one character less), the first tab from the loop doesn't display correctly in my Ubuntu 20.04 terminal.
Why is this?
#include <stdio.h>
int main()
{
printf("some string ===>");
for (int j = 1; j <= 9; ++j) printf("\t%d", j);
printf("\n");
printf("some string===>");
for (int j = 1; j <= 9; ++j) printf("\t%d", j);
printf("\n");
}
Output in my Ubuntu 20.04 terminal
The TAB character means, "move to the next tab stop", where tab stops are usually every 8 characters.
Consider this program:
#include <stdio.h>
int main()
{
int i, j;
for(i = 0; i < 16; i++) {
for(j = 0; j < i; j++) putchar('*');
printf("\tx\n");
}
}
On my computer (with 8-character tabstops), it prints:
x
* x
** x
*** x
**** x
***** x
****** x
******* x
******** x
********* x
********** x
*********** x
************ x
************* x
************** x
*************** x
Your string "some string ===>" is 16 characters long, so after you print it, you're at a multiple of 8, so printing a TAB moves you 8 more spaces to the next multiple of 8 (24).
Your string "some string===>" is 15 characters long, so after you print it, you're one shy of a multiple of 8, so printing a TAB moves you 1 more space, to 16.
Instead of using tabs to align columns, use the width field.
%-20s will left justify the text in a 20 character wide field.
%5d will right justify the text in a 5 character wide field.
If the length of the text is greater than the specified width, the field will be expanded to accommodate the text.
#include <stdio.h>
int main()
{
printf( "%-20s", "some string ===>");
for (int j = 1; j <= 9; ++j) printf("%5d", j);
printf("\n");
printf( "%-20s", "some string===>");
for (int j = 1; j <= 9; ++j) printf("%5d", j);
printf("\n");
}
Related
I need to print centered string inside a frame of square stars pattern.
EXAMPLE:
const char tekst[]="This is example of string programming in C";
int width = 20;
OUTPUT:
********************
* This is example *
* of string progr- *
* amming in C *
********************
If number of spaces that need to be added is odd, excess space should be added to the right.
If the whole word cannot fit in the row, dash is added and word continues in the next row.
Auxiliary strings are not allowed.
Code:
#include <stdio.h>
#include <string.h>
void framed(const char *tekst, int width) {
int i, j = 0, count = 0;
for (i = 0; i < width; i++)
printf("*");
printf("\n");
while (tekst[j] != '\0') {
count++;
if (count == 1)
printf("* ");
printf("%c", tekst[j]);
j++;
if (count + 5 > width) {
printf(" *");
printf("\n");
count = 0;
}
if (j == strlen(tekst))
for (i = 0; i < width - count; i++)
printf(" ");
}
printf("*\n");
for (i = 0; i < width; i++)
printf("*");
}
int main() {
const char tekst[] = "This is example of string programming in C";
int width = 20;
framed(tekst, width);
return 0;
}
This is my output:
********************
* This is example *
* of string progra *
* mming in C *
********************
Could you help me to fix my code for correct output?
Here you take the additional character "* "" *" into account (with a little off-by-one because of >):
if (count + 5 > width)
Here you don't:
for (i = 0; i < width - count; i++)
If you do take them into account, it (the frame) works.
for (i = 0; i <= width - (count +5); i++)
assuming that you also output consistently a little later
printf(" *\n");
I recommend to replace the very magic number 5 with the less magic number of additional characters; 4 for "* *" and to adapt the conditions <= and >.
The other differences to required output (centering instead of left aligning and inserting the "-" correctly have not even been attempted by the shown code, so I assume that they are not part of what is asked about.
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))
When I print out a pyramid, the last line of the pyramid or the base prints out an integer which represents how many hashes, instead of a string of hashes.
like such:
Height: 3
#
##
3
when its supposed to be:
Height 3:
#
##
###
I'm supposed to print out a pyramid with a height based on the user's input, but instead of the base being printed out as a string it prints out an integer of how many hashes there should be for the base. I understand that this is because I'm returning n but I don't know how to go about it in a way where it still returns the loop.
I've tried changing the class to void instead of int, but that throws an error as it's conflicting types. I'm thinking I should print out an empty string but it messes with my bounds.
#include <cs50.h>
#include <stdio.h>
int get_height(string prompt);
int main(void)
{
int ask = get_height("Height: ");
printf("%i\n", ask);
}
int get_height(string prompt) {
int n;
do {
n = get_int("%s", prompt);
}
while (n < 1 || n > 8);
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
printf("#");
}
printf("\n");
}
return n;
}
The last line of output is the height because that is the last thing printed in your main function:
printf("%i\n", ask);
get_height will actually only print n-1 lines because the first iteration (i=0,j=0) is skipped.
the 3 should be output
The problem is this statement;
for (int j = 0; j < i; j++) {
which stops too early. Suggest:
for (int j = i; j >=0; j--) {
The output after making the above change:
#
##
###
3
Novice programmer here trying to print out a 2D array of asterisks. The output I'm trying to achieve is:
*******
*******
*******
*******
That's 7 asterisks with a leading space increment by 1 every row with row 1 starting with 0 leading spaces and row 4 starting with 3 leading spaces.
Only the <stdio.h> library can be used and I'd like to keep using nested for loops. Here's my attempt:
#include <stdio.h>
int main(void)
{
int i, j;
char star[1] = {'*'};
for(i = 0; i < 4; i++)
{
for(j = 0; j < 8; j++)
{
printf("%*c", i, star[0]);
}
printf("\n");
}
return 0;
}
Here's what I'm getting:
********
********
* * * * * * * *
* * * * * * * *
I'd also like for this question to be an opportunity for me to learn good general programming practices and habits from this community so if you could critique my implementation, I'd greatly appreciate it.
Firstly, this does not really have anything to do with multidemensional arrays. Secondly you are using the width format specifier in your printf call
printf("%*c", i, star[0]);
and setting that width to be i. Therefore each time you call
printf("%*c", i, star[0]);
you are specifying the minimum width of the printed output to be i characters. As your output is a single * character this results in whitespace padding.
Thus in your final iteration of your i based loop (i = 3) you are causing the string
' *'
to be printed each time, penultimate iteration (i = 2)
' *'
and so on.
As you don't really need a char array of length 1, you could get your desired output with
for(i = 0; i < 4; i++)
{
if (i > 0)
{
printf("%*c",i,' ');
}
for(j = 0; j < 8; j++)
{
printf("%c", '*');
}
printf("\n");
}
The program you wrote prints space before every star, and that's space length is tied to the 'i' variable'.
You should make it print (spaces * i) before the loop that prints line of 8 stars even starts.
Here is how i would write it.
#include
int main() {
for(int i = 0; i < 4; i++ ) {
for( int p = 0; p < i; p++ ) {
printf(" ");
}
for( int j = 0; j < 8; j++ ) {
printf("*");
}
printf("\n");
}
return 0;
}
Here it is in Python, if you're interested:
for x in range(4):
print ((x * " ") + ("*" * 7))
Apply this same idea of padding the beginning with spaces based on the iteration, and then adding the asterisks
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.