I am just wondering and confused as too why my output is messed up. The code is below. I am a beginner so please excuse my lack of skill. Any help would be very much appreciated.
#include <stdio.h>
int main(int argc, char *argv[])
{
for (int i = 1; i <= 10; i++)
{
for (int j = 1; j <= i; j++)
{
printf("*");
}
printf("\t");
for (int k = 1; k <= 11-i; k++)
{
printf("*");
}
printf("\n");
}
return 0;
}
Gives this output:
My desired output is this:
\t stops at the next reachable tab position, which by default are multiples of 8.
Therefore, if you print ***, it will skip to column 8, but if you print *********, you are already past 8, so it skips to column 16.
The precision and width fields can be use for formatting. Precision will print up to the specified number of characters and width will print at least the specified number of characters. Using an asterisk in either field allows an argument for a variable number of characters.
#include <stdio.h>
int main( void) {
char asterisk[] = "***********";
for (int i = 1; i <= 10; i++)
{
printf ( "%.*s", i, asterisk);//print up to i characters
printf ( "%*s", 15 - i, " ");//print at least 15 - i characters
printf ( "%.*s", 11 - i, asterisk);
printf("\n");
}
return 0;
}
... why my output is messed up (?)
Code uses a tab '\t' which only aligns to the next tab-stop - usual every 8 columns and the stars needed exceed 8.
With judicious use of the '-' flag, field width and precision, code can be simplified to print an array of characters.
#include <stdio.h>
#include <string.h>
int main(void) {
int n = 10;
char stars[n];
memset(stars, '*', n);
for (int i = 0; i < n; i++) {
// +------------- - flag: pad on right
// |+------------ field width: min characters to print, pad with spaces
// || +--------+- precision: max numbers of characters of the array to print
printf("%-*.*s %.*s\n", n, i + 1, stars, n - i, stars);
// | ^^^^^ ^^^^^ precision
// +--------------------- field width
}
}
Output
* **********
** *********
*** ********
**** *******
***** ******
****** *****
******* ****
******** ***
********* **
********** *
Note: stars is not a string as it lacks a null character. Use of a precision with "%s" allows printf() to use a simple character array. Characters from the array are written up to (but not including) a terminating null character.
A tab-stop is not a fixed-width space (e.g. the same as 4 spaces or 8 spaces), it means that the output device should move the caret (or print-head) to the next column position for tabular data. These column positions are at fixed regular intervals, that's why \t** and **\t have different printed widths:
String Output:
"\t**a" " **a" (7 wide)
"**\ta" "** a" (5 wide)
As others have mentioned, printing a tab character move the cursor to the next tab stop, not a certain number of spaces.
After printing the first set of asterisks, print spaces until you've printed enough characters to space out as far as you need.
for (int j = 1; j <= 10; j++)
{
if (j<i) {
printf("*");
} else {
printf(" ");
}
}
I would do like this:
const int rows = 10;
for (int i = 0; i < rows; i++) {
const int width = 10;
const int space = 5;
const int totalw = 2*width + space;
for (int j = 0; j < totalw; j++) {
char ch = j<=i || (j>=width+space && j<(totalw-i)) ? '*' : ' ';
printf("%c", ch);
}
printf("\n");
}
And just for completeness, even though mentioned in other answers. The '\t' character does not have a fixed width.
Related
This question already has answers here:
How do I check out a remote Git branch?
(42 answers)
Closed 1 year ago.
I just started with C programming and have some difficulty implementing a program which is giving a staircase with 'Height' amount of steps.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height;
do
{
height = get_int("Height: ");
}
while(height > 8 || height == 0 || height < 0);
int width = 0;
int length = height;
while(width < height)
{
printf(" ");
printf("#");
for(width = 0; width < height; width++)
{
printf("\n");
}
}
}
The first lines with the Height are working, but I have difficulties with actually writing a staircase. I wanted something like this or similar to this.
Height: 3
#
#
#
I just want to learn how to implement something like this if I face a problem like this in the future. If somebody could help me further I would really appreciate it!
This works:
#include <stdio.h>
int main() {
// gets height input - replace with your get_int method
int height;
printf("Height: ");
scanf("%i",&height);
// loop over all the steps: 0 - height
for (int i = 0; i < height; i++) {
// add a space i number of times (where i is our current step number and so equal to width)
// notice that if we take top left as (0,0), we go 1 down and 1 right each time = current step
for (int j = 0; j < i; j++) {
printf(" ");
}
// finally, after the spaces add the character and newline
printf("#\n");
}
return 0;
}
I see three issues here:
You're printing newlines (\n) instead of spaces ( ).
Why print the single space character?
You're printing the "#" before (what should be) the spaces.
Print a newline after the spaces and the #.
Also... the staircase's width is always equal to its height; it's just the line you're printing that's advancing... that's a bit confusing.
#include <stdio.h>
int main(void)
{
int height = 5;
for(int i=0; i<height; printf("%*s\n", ++i, "#"));
}
Output:
Success #stdin #stdout 0s 5572KB
#
#
#
#
#
I want to make a lines of stars, each line containing more then the previous one. The point of my problem is that I donĀ“t know how to multiply strings in C.
#include<stdio.h>
#include<conio.h>
main()
{
int max = 10
for (int i = 1; i <= max; ++i){
printf("*"*(2 * i - 1);
}
}
You can just repeat printing the desired number of strings.
#include<stdio.h>
#include<conio.h>
main()
{
int max = 10; // a semicolon is added to make it compile
for (int i = 1; i <= max; ++i){
for (int j = 0; j < (2 * i - 1); j++){ // repeat (2 * i - 1) times
printf("*");
}
printf("\n"); // separate lines
}
}
I respect the original code, so some points that are not good (meaningless including of non-standard conio.h and non-standard definition of main() (instead of int main(void))) remains.
The language semantics do not support what you are trying to do. In C a string is not a first class type in any case - it is simply an array of char, so all string handling is performed through functions; you cannot perform direct operations on them; and even if you could I doubt multiply would be one of them - it has a very limited use case easily implemented using simpler operations.
In this case you do not in fact need repeated string replication (or multiply as you refer to it) since you are outputting the string directly so have no need to store the string and the associated memory allocation issues that entails. Rather you simply need repeated string output.
#include <stdio.h>
void printRepeatString( const char* str, int n )
{
for( int i = 0; i < n; n++ )
{
printf( "%s", str ) ;
}
}
int main( void )
{
const int max = 10
for (int i = 1; i <= max; i++ )
{
printRepeatString( "*", (2 * i) - 1 ) ;
putchar( '\n' ) ;
}
return 0 ;
}
An alternative to "multiplying" a string of '*' is to create the longest one and then print a truncated portion of it.
Use "%.*s", n, s to print a character array s up to n characters.
#include<stdio.h>
#define MAX 10
int main(void) {
char s[2 * MAX] = {0};
memset(s, '*', 2 * MAX - 1);
for (int i = 1; i <= MAX; ++i) {
printf("%.*s\n", 2 * i - 1, s);
}
}
Output
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
I'm currently going through CS50 through edx and doing problem set 1, Mario.
The objective is to create a print out using pound signs. With the help of some videos I got the code for the first one but I don't understand fundamentally how the math works/ what the computer is understanding.
So I figure if I don't learn I'm crippling myself later.
if n= 5
Then i has 1 added to it until it is not less than 5 which means 5 times yes?
Take a look at this line for the space loop >
for (int j = 0; j < n -1 - i; j++)
If n is 5, then it ends up being j(0) < 3...
So why on the first line are there four spaces and not three spaces?
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Pyramid Height: ");
}
while (n < 0 || n >= 24);
//print out this many rows
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n -1 - i; j++)
{
printf(" ");
}
// print out this many columns
for (int j = 0; j < i + 2; j++)
{
printf("#");
}
printf("\n");
}
}
I get the correct pyramid yet i don't understand the logic behind the spacing and prints
if n=5 then n-1-j would be equal 5-1-0 i.e. 4 for the first time executing the loop that is the reason why you are seeing four spaces. The first loop condition should be n-2-j if you want the number of spaces to be three because total no of columns is 5 and the pounds expected in the first row are 2, therefore you should be subtracting 2 from n.
That looks way too complicated.
Here's a simple version I whipped up:
#include <stdio.h>
int main(void) {
int height = 5;
char blocks[height];
memset(blocks,'#',height);
for(int i=0; i<height; ++i)
{
printf("%*.*s\n", height, i+1, blocks );
}
return 0;
}
Output:
Success #stdin #stdout 0s 9424KB
#
##
###
####
#####
Let us try to figure out the pattern here. Like for the left pyramid if the height of the pyramid is 8, check the pattern of spaces and hashes from top to bottom. In this case we need 8 lines, every line has same characters and no of spaces decreases and no of hashes increases from top to bottom.
Now we have the pattern for the left half, the right half is the same, mirror image. So now we can write down the loop as we know the no of spaces and hashes from top to bottom. In programming we need to understand the underlying principle. Plug in the code afterwards becomes easy.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int h;
do
{
h = get_int("Pyramid height: ");
}
while (h<1 || h>8);
int n = 8, i, j;
for (i=0; i<h;++i)
{
// left half
for (j=0;j<h-1-i;++j)
printf(" ");
for (j=0;j<i+1;++j)
printf("#");
// two spaces in middle
printf(" ");
// right half, we have omitted the space code as it is not required.
for (j=0;j<i+1;++j)
printf("#");
printf("\n");
}
return 0;
I am still new to C, and I need to figure a way to print the same number of stars as the number of frequencies.
Here's my code:
int arrayHistogram(int array[]){
int i;
int j;
int count=0;
int freq[SIZE];
char stars[SIZE];
for(i = 0; i < SIZE; i++){
count =1;
for(j = i+1; j < SIZE; j++){
if(array[i]==array[j]){
count++;
freq[j]=0;
}
}
if(freq[i] != 0){
freq[i] = count;
}
}
//for ( i = 0; i < SIZE; i++){
//int num = freq[i];
//stars[i]= '*'*num;
}
printf("Value ");
printf("Frequency ");
printf("Histogram\n");
for(i = 0; i < SIZE; i++){
if(freq[i] != 0){
printf("%5d%10d%10d\n", array[i], freq[i], stars[i]);
}
}
}
I know that I can't multiply char by int here to print the stars, but I put here just to show where I need to print those stars (i.e. the histogram).
My Output:
Value Frequency Histogram
7 4 -46
8 3 126
4 6 84
Expected output:
Value Frequency Histogram
7 4 ****
8 3 ***
4 6 ******
Well, you already know everything to do that i.e. loop.
Simply, loop up to a frequency and print that many stars.
Something like this (pseudo code):
loop until freq[i]
print '*'
end loop
It's just an idea. You know how a loop works. Just put a nested loop (i.e. for loop) where you need to print the stars. Mind the newline. You need a newline at the end of each line after printing the stars.
UPDATE:
As observed, you've frequencies up to 10 i.e. a fixed size that you already know. You can simply use a string of stars and then print it using printf() with %.*s format specifier with field width and string length.
Here's an example (live code):
#include <stdio.h>
#define SIZE 10
int main(void)
{
const char* stars = "**********";
const int freqs[ SIZE ] = { 3, 5, 6, 2, 0, 7, 10, 9, 4, 8 };
for ( int i = 0; i < SIZE; i++ )
{
printf("%5d \t %10.*s\n", freqs[i], freqs[i], stars);
}
return 0;
}
OUTPUT:
3 ***
5 *****
6 ******
2 **
0
7 *******
10 **********
9 *********
4 ****
8 ********
how about building char stars[SIZE] with a loop?
int nStars = freq; // in you situation.
for(int i=0; i < nStars;++i)
{
stars[i] = '*'; // set char i to be '*'
}
stars[nStars] = '\0'; // don't forget to terminate your string
you can make a simple utility function void fillChar(char* buff, char ch, int count); of it.
Take Caution not to exceed the size of the allocated string or bad things gona happen.
Cheers.
I am using C as my programming language (not C++) and I am required to encrypt whatever the user types in using a 2-rail fence cipher method of coding in C, AND then pad whatever empty space there is left in the encrypted name with an 'x'. Because it's 2-rail fence the empty space happens if the output string has ODD number of characters!
Here is an example.
Let's say someone write this name: andredimera (all lowercase, no space). The name is 11 characters long. If padding with the x is done correctly, the encrypted name should give me this output WITH the padding -->
adeiea
nrdmrx
adeieanrdmrx
But I keep getting this output without the padding-->
adeiea
nrdmr
adeieanrdmr
This is FRUSTRATING! This has been a class quiz for almost a week now, I have not done well, and nobody has been able to help me out no thanks to my short-term memory. I would really appreciate this if someone can help me solve this, with an explanation on how you came up with the solution, so I can get it right in future endeavors. I don't want just the hint or explanation for me to go fish it out myself. I've had my share of it already this week. Thank you. I appreciate your help. :)
Oh, and here is my code:
UPDATED: Code was reposted because I was stupidly compiling it in a completely different solution. That code should work now.
Which now brings me to my latest question based on my updated code: how can I make my char pad = 'x' be added into my char str if the user input has odd number of characters?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
char row, col;
char str[100][100];
char pad = 'x';
printf("****Welcome to The Caesar's Palace for Encrypted Names****");
printf("\n Please enter your name: ");
scanf("%s", str);
printf("You entered: %s\n", str);
printf("2-RAIL CIPHER ENCRYPTION:\n");
for (row = 0; row < 1; ++row)
{
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col]);
}
printf("\n");
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col + 1]);
}
}
printf("%c", pad);
printf("\n");
for (row = 0; row < 1; ++row)
{
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col]);
}
for (col = 0; col < 12; col += 2)
{
printf("%c", str[row][col + 1]);
}
}
printf("\n");
printf("\n");
return 0;
}
There are a number of fundamental issues that are giving you problems. The biggest being the understanding of what a character, character array and string is in C, and how to declare/initialize each. Your pad is a single char, there are no additional dimensions required during the declaration and initialization. It is simply:
char pad = 'x';
A character array is just that multiple characters. In C, if the contents of a character array is nul-terminated, then it can be used as a string. Without the nul-termination it is simply an array of characters.
In your case, you are attempting a 2-Rail cipher with a key (number of rows of text) of 2. Meaning you will simply stagger the characters from the name read from the user between the top-rail and bottom-rail across two lines. e.g.
word: ALLIGATOR
len : 12 characters max (11 char + nul-terminator)
key : 2 (number of lines of text)
0 1 2 3 4 5 6 7 8 9 10
------------------------- rail 1
A x L x G x T x R x x
x L x I x A x O x x x
------------------------- rail 2
The string you take as input need only be a single-dimension array of characters (nul-terminated). As such, your declaration of str, with the number of columns (NCOL = 12), need only be:
char str[NCOL] = ""; /* a 12 character array initialized to 0 (empty string) */
Since your row and col variables are used as array indexes, they should properly be type int instead of type char. (that is another compiler warning)
The remainder of your code, isn't far off. There is no need for the outer row loop in your 2-Rail cipher code, iterating from 0 < 1 with only execute once.
Your padding issue is simply due to the way the rail-cipher works. For each line in key you add, you need to add that number of padding characters. (e.g after the original line, for the 1st line, you add one x before the text, 2 before the second, etc..) In your case, you are simply missing one x before the line following the original. You can correct the issue here with a simple:
printf ("\nx");
between the column loops.
Putting those pieces of the puzzle together with a few more corrections (such as preventing overrun of str by a field-width limitation in scanf, etc.), you could do something like:
#include <stdio.h>
enum { KEY = 2, NCOL = 12 }; /* simple decalration of 2 constants */
int main (void) {
char str[NCOL] = "";
char pad = 'x';
int row, col;
printf ("\n****Welcome to The Caesar's Palace for Encrypted Names****\n");
printf ("\n Please enter your name: ");
scanf ("%11[^\n]%*c", str);
printf (" You entered: %s\n\n", str);
printf ("2-RAIL CIPHER ENCRYPTION:\n\n");
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col], pad);
}
printf ("\nx");
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col + 1], pad);
}
printf ("\n\n Your new name is now \n\n");
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col], pad);
}
for (col = 0; col < NCOL; col += KEY) {
printf ("%c%c", str[col + 1], pad);
}
printf ("\n\nCAESAR CIPHER ENCRYPTION:\n\n");
printf (" Your new name is now\n\n");
for (row = 0; row < NCOL; ++row) {
char c = str[row];
c = (char) (c + KEY + 1);
printf ("%c%c", c, pad);
}
printf ("\n");
printf ("\n");
printf ("The End\n");
return 0;
}
Example Use/Output
$ ./bin/railcipher
****Welcome to The Caesar's Palace for Encrypted Names****
Please enter your name: ALLIGATOR
You entered: ALLIGATOR
2-RAIL CIPHER ENCRYPTION:
AxLxGxTxRxx
xLxIxAxOxxx
Your new name is now
AxLxGxTxRxxLxIxAxOxxx
CAESAR CIPHER ENCRYPTION:
Your new name is now
DxOxOxLxJxDxWxRxUxxxx
The End
note: I make no representations about the correctness of your CAESAR cipher and I'm no expert on rail-ciphers, but the syntax and code corrections must be dealt with before you tweak the ciphers. Look over the changes and let me know if you have any questions.
Here are what you need to do to fix your codes:
Step 1 Add a define hashtag and the include string library to the top of your code...
#include <string.h>
#define BUFFER_SIZE 100
Step 2 Replace these following members that you have...
char row, col;
char str[100][100];
char pad = 'x';
...to these ones
int col, size;
char str[BUFFER_SIZE];
Step 3: Right below your scanf, define your size with a strlen. Strlen calculates and returns to you the length of a string. Any string that you input. This is my strlen for your problem. Use it. ;)
size = strlen(str);
Step 4:
From 2-Rail cipher encryption till the last printf function, replace your code to the ones below.
for (col = 0; col < size; col += 2)
{
printf("%c", user[col]);
}
printf("\n");
for (col = 0; col < size; col += 2)
{
//printf("%c", user[col + 1]);
if (col + 1 != size)
printf("%c", user[col + 1]);
else
printf("x");
}
printf("\n");
for (col = 0; col < size; col += 2)
{
printf("%c", user[col]);
}
for (col = 0; col < size; col += 2)
{
if (col + 1 != size)
printf("%c", user[col + 1]);
else
printf("x");
}
In case you need explanation, your issue was simple, you had an extra row in your C-string that the program was not using. Additionally, you needed the strlen and an if function that basically says "if you've reached the end of the character string in an array of more than 100 characters, then print an x. If you did not have that code in the program would either print nothing (as stated in your issue) or print a zero.
But, keep in mind that if you type in a super long C-string name that is more than 100+ characters and you have the x padding at the end, it will cause some memory issue. Just food for thoughts.
But from now, do these steps and your codes should work with the output you wanted. (hopefully it should). This was my ouput.
adeiea
nrdmrx
adeieanrdmrx