Print string inside frame - c

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.

Related

Programming in C - CS50 Mario pyramid blocks print - For loops difficulties

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))

Does less loop in rhombus shape printing always faster than using more loops? Is there a way to print rhombus shape using 1 loop?

I wanted to print a rhombus shape with only 1 loop. The furthest I have gone is using 2 for loops.
The result shape is as follows:
rhombus shape
*
* *
* *
* *
* *
* *
* *
* *
*
The code for using 3 loops is as follows:
#include <iostream>
int main() {
int i, j;
int columns = 4;
for(i = 0; i < columns; i++){
for(j = 0; j <= (columns-1) - i;j++){
printf(" ");
}
for(j = 0;j<=2*i;j++){
if(i == 0||j == 0||j == 2*i){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
for(i = columns; i >= 0; i--){
for(j = 0; j <= (columns-1) - i;j++){
printf(" ");
}
for(j = 0;j<=2*i;j++){
if(i == 0||j == 0||j == 2*i){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
}
My code is as follows:
int main() {
int i, j;
int columns = 4;
for(i = 0; i < columns; i++){
for(j = 0;j<=(2*i+(columns) - i);j++){
if(j==columns/2+(columns/2-i)||(j == (2*i+(columns) - i))){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
for(i = columns; i >=0; i--){
for(j = 0;j<=(2*i+(columns) - i);j++){
if(j==columns/2+(columns/2-i)||(j == (2*i+(columns) - i))){
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
}
I have the following questions:
Does less loop in rhombus shape printing always faster than using more loops?
Is there a way to print rhombus shape using 1 loop? Without using predefined functions like string().
Sorry for my English, looking forward to hearing from you guys.
Let's address the questions in order...
Does less loop in rhombus shape printing always faster than using more loops?
Firstly, you should not be concerned about speed in a program like this. Except maybe if you are trying to print a HUGE rhombus or this is intended to run on a small battery-operated embedded device requiring low power consumption.
I don't think you're doing any of these.
The answer really is no: both your approaches are doing roughly the same amount of looping. They're not very efficient, because they are calling a fairly expensive function once for each character output.
More importantly, the code is overly complicated, unclear and difficult to read. You should be focusing here, instead of worrying about trivial performance considerations.
Is there a way to print rhombus shape using 1 loop? Without using predefined functions like string().
Yes, I posted an example in the comments where you can just use a specifier in the printf call to output some amount of padding. Internally, that does basically the same thing as your own loops, but it makes shorter, clearer code and fewer printf calls.
Here, you just work out how many spaces are required before the * and then how many after it. You can then ask printf to output the string "*" padded with some number of spaces. Use %*s to indicate there are two parameters: the total width of the string, and the string itself. The width will be the number of spaces you want, plus 1 for the actual string.
#include <stdio.h>
#include <math.h>
int main(void)
{
const int N = 4;
for (int i = 0; i <= N*2; i++)
{
int space_before = abs(N - i);
int space_after = 2 * (N - space_before ) - 1;
if (space_after > 0)
printf("%*s%*s\n", space_before + 1, "*", space_after + 1, "*");
else
printf("%*s\n", space_before + 1, "*");
}
return 0;
}
Now, this is easier to understand, but it's still a bit clunky. How about we move it into a function, and then get rid of the branching in the loop. All the loop iterations output two stars except the first and last ones which are simpler. So, here:
#include <stdio.h>
#include <math.h>
void display_rhombus(int size)
{
if (size > 0)
{
printf("%*s\n", size + 1, "*");
for (int i = 1; i < size*2; i++)
{
int space_before = abs(size - i);
int space_after = 2 * (size - space_before ) - 1;
printf("%*s%*s\n", space_before + 1, "*", space_after + 1, "*");
}
}
printf("%*s\n", size + 1, "*");
}
int main(void)
{
display_rhombus(4);
return 0;
}
Now, you have a function with a name that describes what it does, has simple-to-understand code, and is re-usable. You can call it many times to draw whatever sizes of rhombus you want.
int main(void)
{
for (int size = 0; size < 10; size++)
{
display_rhombus(size);
}
return 0;
}
Finally, I should also mention that it's possible to output a rhombus with no loops, using a technique called recursion. I will leave that as a learning exercise for you.
Well, apart from paddy's excellent answer, here's another one:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
void printStar(int size) {
int j = size / 2;
int i = size % 2 == 0 ? j - 1 : j;
bool flag = false;
while (i <= j) {
std::vector<char> vec(size, ' ');
vec.at(i) = '*';
vec.at(j) = '*';
std::copy(vec.begin(), vec.end(), std::ostream_iterator<char> {std::cout});
std::cout << "\n";
if (!flag) {
i--;
j++;
}
else {
i++;
j--;
}
if (i == -1) {
flag = true;
i += 2;
j -= 2;
}
}
}
int main() {
printStar(5);
return 0;
}

VSS C coding to print out a Christmas tree

This is my current code
void printer(int input)
{
int star;
int space;
for (int i = 1; i <= input; i++)
{
star = i;
space = i + input - star - 1;
for (int j = 0; j < space; j++)
{
printf(" ");
}
for (int s = 0; s < star; s++)
{
printf("*");
}
printf("\n");
}
}
I'm trying to print it out like
How tall 3?
*
* *
* * *
_| |_
\___/
and this is what i get. What is wrong with my code? and how will I fix the code?
How Tall? 3
*
**
***
Essentially, this snippet of code here that you use:
star = i;
space = i + input - star - 1; // or, space = input - 1 + i - star;
is the same as writing:
star = i;
space = input - 1;
This is because i and star have the same value (quoth star = i), and therefore, negate each other.
Now, can you see a constant here? Yes, the value of input is never changed anywhere, and therefore your code is always what 1 less than the input is. (In this case, its always preceded by 2 (=3-1) spaces) like this:
*
**
***
^^ mark two spaces
And you also forgot to add a trailing space after the asterix and hence there is no spacing between them.
Therefore, to solve your problem, you could store the value of input temporarily and reduce it by 1 in every iteration so it appears like a pyramid.
Example:
void printer(int input)
{
int star;
int space;
// Store the original length of the space
int space_length = input;
for (int i = 1; i <= input; i++)
{
star = i;
// Get the number of spaces for the current iteration
space = space_length - 1;
for (int j = 0; j < space; j++) {
printf(" ");
}
for (int s = 0; s < star; s++) {
printf("* ");
// ^ note this space after the asterisk
}
// Decrease the length of the space every step
// So that it appears like a slope
// Note how we are using 'space_length' instead of input
// This is because if we decrement 'input', this loop
// will get affected, which is not what we want
space_length--;
printf("\n");
}
///////// bottom part of the tree /////////
// number of spaces needed = input - length of "_| |_" - 1
for (int i = 1; i <= input - (4 - 1); i++)
printf(" ");
printf("_| |_\n");
// number of spaces needed = input - length of "\\___/" - 1
for (int i = 1; i <= input - (4 - 1); i++)
printf(" ");
printf("\\___/\n");
}
which gives the output:
*
* *
* * *
_| |_
\___/
your format is the issue. as you already know the size of the tree, you can deduct the size of the first set of whitespace (the first spaces on each lines), being spaces = (size - 1) - i. it should be, for each i:
i1 = 2
i2 = 1
i3 = 0
which seems to be what the result gives. additionally, between all asterix, just insert one space until the last character, and that's the idea
There are too many things gone wrong with this. I'll not post the correct code, but can guide you through it.
Since you want space after stars, print "* " instead of "*"
You have to use decremental space in beginning, before printing star, there's some logical fault in that, which is, you are adding and subtracting i and star, which are same thing. You need to give (input - star) spaces for the loop.
For the trunk, you have to develop some symmetrical logic.
I hope it helps you.
You can do it like this:
#include <stdio.h>
void printer(int input)
{
// for stars
for (int i = 1; i <= input; i++) {
for (int j = 1; j <= input - i; j++) {
printf(" ");
}
for (int k = 1; k <= i; k++) {
if (k == 1) printf("*");
else printf(" *");
}
printf("\n");
}
// for base
int base_half_len = input - 1;
for (int i = 1; i < base_half_len; i++) {
printf("_");
}
printf("| |");
for (int i = 1; i < base_half_len; i++) {
printf("_");
}
printf("\n\\");
for (int i = 1; i < 2 * input - 2; i++) {
printf("_");
}
printf("/\n");
}
int main(void) {
// your code goes here
printer(10);
return 0;
}
Here's the link where I tested it: https://ideone.com/7zpNeW

how to create a diamond in c using only 3 printf and 3 n\t\

I am attempting to create a diamond in c with the constraints of only 3 printfs and 3 n\t. this requires me to use loops. I know how to make an upside down triangle and a triangle but cant use that because there are too many printfs. i will attach my code so far. I am aware it does not make a diamond, and some awfully strange shape, but that it what i'm trying to work off and edit to make into a diamond, I just haven't been able to figure it out.
if (type_of_shape == 5)
{
for (i = 0; i < width; i++)
{
for (j = 0;j < ((width - 1) / 2) - i ||(width -1)/2 < i && j + (width-1)/2 < i; j++)
{
printf(" ");
}
for (k = 0;k<width && k < (j*2+1) ; k++)
{
printf("*");
}
printf("\n");
}
}
//int width = 5;
int row, col;
int spaces, stars;
int half, rate;
half = width / 2 + 1;
rate = 1;
for(row = 1; 0 < row && row <= half; row += rate) {
spaces = half - row;
stars = row * 2 -1;
printf("%*s", spaces, "");
for (col = 0; col < stars; col++)
printf("*");
printf("\n");
if(row == half)
rate = -rate;
}
I got it down to a single line which has a single loop, with a single printf statement.
It involved some tricky use of abs.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int w = 9;
for(int l=0; l < w; ++l) printf("%*.*s\n", abs(w/2 - l)+abs((2*l+1)-(2*l+1>w)*2*w), abs((2*l+1)-(2*l+1>w)*2*w), "**************");
return 0;
}
2 loops (one for, one while).
2 printf statements.
Note:
This works with odd Widths.
An even width produces a diamond with Width+1
My IDEOne code
int main(void)
{
int width = 9;
int layer;
width+=2;
for(layer=0; layer<width/2; ++layer)
{
printf("%*.*s\n", width/2+layer + 1,layer*2 + 1, "**************************");
}
layer--;
while (layer --> 0)
{
printf("%*.*s\n", width/2+layer + 1,layer*2 + 1, "**************************");
}
return 0;
}
Output
Success time: 0 memory: 2168 signal:0
*
***
*****
*******
*********
*******
*****
***
*
Here's a solution with no loops at all. (looping accomplished via recursion), and 3 printf statements:
#include <stdio.h>
void drawDiamond(int width, int stars)
{
static const char* txt = "*****************************";
if (stars == width) {
printf("%*.*s\n",width, width, txt);
return;
}
printf("%*.*s\n", (width+stars)/2, stars, txt);
drawDiamond(width, stars+2);
printf("%*.*s\n", (width+stars)/2, stars, txt);
}
int main(void)
{
drawDiamond(9, 1);
return 0;
}

How do I print out this 2D array?

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

Resources