While practicing I came across an assignment that required me to write a code which would print out the following shape:
https://postimg.cc/hJ7Hc72W
I tried a method where I had two for loops. I know the basic guidelines when it comes to printing star shapes but I simply can't complete this one. Whatever I do, I can just print out the left portion of the shape(the left pyramid) but the right one ends up being "warped".
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i,j;
printf("Enter n: ");
scanf("%d", &n);
int length=2*n-1, width=2*n+1;
for(i=0; i<length; i++) {
for(j=0; j<width; j++) {
//The left side of the "||" separated condition prints the left pyramid,
// while the right side of the "||" should print out the right pyramid
if( (i>=j && i<=length-1-j) || (i<=j && i>=length-1-j) )
printf("*");
else printf(" ");
}
printf("\n");
}
return 0;
}
However, what I end up with is always this: https://postimg.cc/628SY4G1
Any idea where I might be wrong? Thanks so much!
Instead of looping over everywhere and filtering to determine which character to print (as you have noticed, this is surprisingly tricky to get right), break the figure down into sections.
Start with printing a single line, width wide and with stars stars.
This can be done with three loops:
void print_line(int width, int stars)
{
for (int i = 0; i < stars; i++)
printf("*");
for (int i = 0; i < width-2*stars; i++)
printf(" ");
for (int i = 0; i < stars; i++)
printf("*");
printf("\n");
}
Then write a loop for the top n-1 lines and a loop for the bottom n-1 lines, with one full-width line inbetween:
int width = 2*n+1;
for (int i = 1; i <= n-1; i++)
print_line(width, i);
print_line(width, n);
for (int i = n-1; i >= 1; i--)
print_line(width, i);
This way works:
#include <stdio.h>
int main()
{
int n,i,j,k;
printf("Enter n: ");
scanf("%d", &n);
int length=2*n-1;
int reqd_no_of_stars;
for(i=0; i<=length; i++)
{
if(length+1-i<i)
{
reqd_no_of_stars=length+1-i;
}
else
{
reqd_no_of_stars=i;
}
for(k=0; k<reqd_no_of_stars; k++)
printf("*");//print left set of stars equal to the number of reqd_no_of_stars
for(k=0; k<(2*n+1)-2*reqd_no_of_stars; k++)
printf(" ");//print required spaces=total_width-required_width_for_stars=((2*n+1)-2*reqd_no_of_stars) in between stars of both sides
for(k=0; k<reqd_no_of_stars; k++)
printf("*");//print right set of stars equal to the number of reqd_no_of_stars
printf("\n");
}
return 0;
}
If you structure your code, you'll have very little problem in painting the ties:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const char AST[] = "**********";
static const char BLK[] = " ";
void paint_line(const char *s, int n)
{
int l = strlen(s);
while (n >= l) {
fputs(s, stdout);
n -= l;
}
/* n < l */
if (n > 0)
printf("%.*s", n, s);
}
void paint_tie(int n)
{
int row;
for(row = 1; row <= n; row++) {
paint_line(AST, row);
paint_line(BLK, 2*(n-row) + 1);
paint_line(AST, row);
printf("\n");
}
for (row = n-1; row > 0; row--) {
paint_line(AST, row);
paint_line(BLK, 2*(n-row) + 1);
paint_line(AST, row);
printf("\n");
}
}
int main(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++) {
int n = atoi(argv[i]);
paint_tie(n);
}
}
The routine main() just extracts the sizes of the ties from the command line. I've not included code to check if atoi(3) returns the proper value, but for sure you can complete the exercise.
The routine paint_tie() prints one tie, it just prints the lines with the number of characters that are requested, growing up to n, then waning to zero again.
Finally, the routine paint_line just paints a sequence of chars, selected from a string passed as a parameter. It prints as many complete strings (just trying to be efficient) using the function fputs(3) until there's no more place for a full string, it then uses (only once, as that's expensive) the %.*s format, which allows me to get the first part of the string, up to the trailing characters that are not multiple of the string length. You can download the example here.
BTW, why do you ask this? Is it a homework exercise, or you are just practicing (as you say in your question) Any case, you are doing bad just asking here, as you are not exercising yourself. Why do you auto ask to do an exercise, and then come here to look for the answer? Cannot understand.
Related
I am working on an old exam and the problems states that a given array (int zahlen[]={1,4,5,1,5,7,9,2,3,4}) has values that are the same. The task is to replace the values that are the same with '-1'. After each replacement, a given variable, count, has to be increased by one.
My problem is that the variable count is two-times higher than normal (In this case there are only 3 of the same numbers and the variable shows 6.)
The function is called array_unique. I am would be grateful for a brief explanation of my mistake.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("chcp 1252");
int zahlen[]={1,4,5,1,5,7,9,2,3,4};
int len = sizeof(zahlen)/sizeof(int);
int erg = array_unique(zahlen,len);
printf("Es wurden %d doppelte Zahlen gelöscht: \n",erg);
printf("Das Array hat nun folgende Werte: ");
printArrayUnique(zahlen,len);
return 0;
}
void printArrayUnique(int *array, int len){
for(int i=0; i<len; i++){
if(array[i]!=-1){
printf("%d ",array[i]);
}
}
}
int array_unique(int *array, int len){
int count=0;
for(int i=0; i<len;i++){
for(int j=i+1; j<len;j++){
if(array[i]==array[j]){
array[j] = -1;
count++;
}
}
}
return count;
}
I have not figured out any other solution to fix the faulty value of count.
The issue is due to the fact that your are counting duplicates more than once; so, when you have found a duplicate entry, you correctly replace that with -1 but then, later in the loops, you will be (potentially, at least) comparing two or more of those -1 values.
Just add a check that either value is not -1 (along with the test for equality) before incrementing the count variable:
int array_unique(int* array, int len)
{
int count = 0;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (array[i] == array[j] && array[j] != -1) {
array[j] = -1;
count++;
}
}
}
return count;
}
Note also that, as mentioned in the comments, you really do need declarations of your functions before you use them. Add the following two lines before the main function:
void printArrayUnique(int* array, int len);
int array_unique(int* array, int len);
I want to copy my array over to a pointer, so I can sort the array without changing the original. I'm not getting any errors, and am at a dead end. I've tried printing the pointer's contents, but it's always junk data. If anyone could help me it'd be much appreciated.
#include <stdio.h>
void bubbleSort(char *array[], int arrIndex);
void displaySort (char *array[], int arrIndex);
int main (void)
{
int index;
int count = 0;
printf("Enter number of people (0 - 50): ");
scanf("%d", &index);
index -= 1;
char userLastFirst[25][index];
int userAge[index];
//defining pointer
char *namePtr[25][index];
//do while loop, loops while count is less than or equal to the index
do{
printf("Enter name %d (last, first): ", count);
scanf(" %[^\n]s", userLastFirst[count]);
printf("Enter age %d: ", count);
scanf("%d", &userAge[count]);
// printf("\n\n%s %d\n\n", userLastFirst[count], userAge[count]);
count++;
} while (count <= index);
//assigning values to pointer
for(int i = 0; i < index; i++){
namePtr[25][i] = &userLastFirst[25][i];
}
//does not print values of pointer
for(int i = 0; i < index; i++){
printf("value of ptr[%d] = %s\n", i, namePtr[i]);
}
bubbleSort(*namePtr, index);
displaySort(*namePtr, index);
return 0;
}
void bubbleSort(char *array[], int arrIndex)
{
for (unsigned int pass = 0; pass < arrIndex - 1; ++pass) {
for (int i = 0; i < arrIndex - 1; ++i) {
if (array[i] < array[i + 1]) {
int temp = *array[i];
*array[i] = *array[i + 1];
*array[i + 1] = temp;
}
}
}
}
void displaySort(char *array[], int arrIndex)
{
for(int i = 0; i < arrIndex; i++){
printf("%s",*array[i]);
}
}
Sorry it's a lot, but I've looked everywhere, and am not exactly sure what the problem is. I suspect it's how I pass pointers thru the functions, or how I'm using * and & but am not totally sure what I'm doing wrong. The for loop below the one that assigns the array values to the pointer is for testing. It's supposed to print out the values I had given it in the previous for loop, but it doesn't. It just prints junk data.
There are couple of issues here, and since I don't know what exactly you want your final code to look like, I am going to give a few examples of what is wrong and how you could possibly fix that.
char userLastFirst[25][index];
This should be
char userLastFirst[index][25];
You don't want 25 people with names up to index characters in them, but rather index people with names up to 25 characters int them.
char *namePtr[25][index];
should be
char namePtr[index][25];
Same as before + you don't need the * here. Since you decided to go with vla let's stick with it. You would use * and more specifically char ** if you went with malloc/calloc.
namePtr[25][i] = &userLastFirst[25][i];
rather than doing this awkward copying, try:
strcpy(namePtr[i], userLastFirst[i]);
it copies the entire string for you, rather than just a single character. You will need to #include the <string.h> library for that.
void bubbleSort(char *array[], int arrIndex)
The first bubble sort argument should be:
char array[][25] // the same in displaySort
if you want to do it without the hassle of malloc/calloc.
And also don't go with int as your temp type. Rather do char temp[25] and copy them around with strcpy.
And don't compare strings with <, it doesn't work in C. Use strcmp for that.
And that's it for doing it without malloc/calloc, here's an example code:
#include <stdio.h>
#include <string.h>
void bubbleSort(char array[][25], int size);
void displaySort(char array[][25], int size);
int main (void)
{
int num_of_people;
printf("Enter number of people (0 - 50): ");
scanf("%d", &num_of_people);
char original_array[num_of_people][25];
char copied_array[num_of_people][25];
for (int i = 0; i < num_of_people; i++) {
printf("Enter name %d (last, first): ", i);
scanf(" %[^\n]s", original_array[i]);
}
for(int i = 0; i < num_of_people; i++){
strcpy(copied_array[i], original_array[i]);
}
bubbleSort(copied_array, num_of_people);
displaySort(copied_array, num_of_people);
return 0;
}
void bubbleSort(char array[][25], int size)
{
for (int i = 0; i < size - 1; ++i) {
for (int j = 0; j < size - 1 - i; ++j) {
if (strcmp(array[j], array[j + 1]) > 0) {
char temp[25];
strcpy(temp, array[j]);
strcpy(array[j], array[j + 1]);
strcpy(array[j + 1], temp);
}
}
}
}
void displaySort(char array[][25], int size)
{
for(int i = 0; i < size; i++){
printf("%s\n",array[i]);
}
}
and the program work like this:
Enter number of people (0 - 50): 4
Enter name 0 (last, first): Kowalski, Jan
Enter name 1 (last, first): Kowalska, Anna
Enter name 2 (last, first): Nowak, Miłosz
Enter name 3 (last, first): Amper, Ohm
Amper, Ohm
Kowalska, Anna
Kowalski, Jan
Nowak, Miłosz
I hope this is something you wanted to achieve.
'scanf' won't pass on my the value n into the for loop
appreciate your time to help thanks. terminal prints the size of array. I hope to scan for that value and call it 'n' . This value 'n' is then suppose to be passed down to the loop where random numbers less then 999 are assigned to different parts of the array.
#include <stdio.h>
#include <stdlib.h>
int n;
int arraySize;
int randN;
int rand();
int parameter = 999;
int main()
{
printf("What is the size of the array\n");
scanf("%d\n", &n);
//here is the scanf
int i;
for(i = 0 ; i < n; i++ )
{
int array[n];
randN=rand();
if (randN <= parameter)
{
array[i]=randN;
return 0;
}
return 0;
}
}
The array is declared as the first line in the body of the loop.
This means, for every loop iteration, the array is created, one element is set, and then the array ceases to exist.
If you want the loop to populate the whole array, declare the array BEFORE the loop. That will also ensure the array can be used AFTER the loop .... with all its elements as populated in your loop.
Drop the \n at the end of format string. scanf tries to get input as specified in the format string, the \n forces the user to enter additional newline
scanf("%d", &n);
See answer of user3279954
See comment of AnT
the "return 0;" statements will terminate your program in the first iteration of the loop, regardless of the value returned in the call to rand()
Also: Don't declare library functions (like rand()) yourself, instead, include the appropriate header file, here stdlib.h which was included already.
#include <stdio.h>
#include <stdlib.h>
int n;
int arraySize;
int randN;
int parameter = 999;
int main()
{
printf("What is the size of the array\n");
scanf("%d", &n);
int array[n];
int i;
for (i = 0 ; i < n; i++ )
{
// This loop below should be optimized for any productive use
// easy solutions like random%1000 (yielding values from 0
// to 999) will bias some values over others.
do {
randN=rand();
} while (randN > parameter);
// This loop above should be optimized for any productive use
array[i]=randN;
}
for (i = 0 ; i < n; i++ )
{
printf("%i ", array[i]);
}
return 0;
}
Ok, so there are some things with your code:
#include <stdio.h>
#include <stdlib.h>
int n;
int arraySize;
int randN;
int rand();
int parameter = 999;
int main()
{
printf("What is the size of the array\n");
scanf("%d", &n); // remove the \n
// in C, you have to use a const to create an array
const int arrSize = n;
// create the array BEFORE, entering the for loop
int array[arrSize];
int i;
for(i = 0 ; i < n; i++ )
{
// this guarantees that you will get a number less than "parameter"
randN=rand() % parameter;
array[i]=randN;
// return 0; you don't want this return
}
// so you can see what got stored
for(i = 0 ; i < n; i++ )
printf("%d ", array[i]);
return 0;
}
EDIT: added a printf for the values in the array
I'm trying to sort elements in an array from smallest to largest that a user inputs along with the size. This is my code so far:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXVALUES 20
void sort(int *A[], int n) {
int i, tmp, j;
for (i = 0; i <= (n - 2); i++) {
for (j = (i + 1); j <= (n - 1); j++) {
if (*A[i] > *A[j]) {
tmp = *A[i];
*A[i] = *A[j];
*A[j] = tmp;
}
}
}
return;
}
int main(int argc, char *argv[]) {
int n, A[MAXVALUES], i;
printf("Enter an array and no. of elements in array: ");
scanf("%d%d", &A[MAXVALUES], &n);
sort(A[MAXVALUES], n);
printf("Ordered array is: \n");
for (i = 0; i <= (n - 1); i++) {
printf(" %d", A[i]);
}
return 0;
}
The compiler compiles it without any errors but it stops working after I put in the inputs. I've yet to quite grasp the theory behind arrays and pointers so could someone tell me where in my code I'm going wrong?
scanf("%d%d", &A[MAXVALUES], &n); is the problem
That's not how you read an array.
First you read the n, after that inside a loop you read every element like
scanf("%d", &A[i]); where i is the index from 0 to n
EDIT:
scanf("%d", &n);
int i = 0;
for(i = 0; i < n; i++)
{
scanf("%d", &A[i]);
}
This is what you want.
You can't use scanf() to read in a whole array at once.
This:
scanf("%d%d", &A[MAXVALUES], &n);
Makes no sense; it passes scanf() the address of the element after the last one in A, causing undefined behavior. The sort() call is equally broken.
To read in multiple numbers, use a loop. Also, of course you must read the desired length first, before reading in the numbers themselves.
Firstly I'll tell you a couple of things about your sorting function. What you want, is take an array (which in C is representable by a pointer to the type of elements that are in that array, in your case int) and the array's size(int) (optionally you can take a sorting method as an argument as well, but for simplicity's sake let's consider you want to sort things from lowest to highest). What your function takes is a pointer to an array of integers and an integer (the second argument is very much correct, or in other words it's what we wanted), but the first is a little more tricky. While the sorting function can be wrote to function properly with this argument list, it is awkward and unnecessary. You should only pass either int A[], either int *A. So your function header would be:
void sort1(int *A, int n);
void sort2(int A[], int n);
If you do this however, you have to give up some dereferencing in the function body. In particular I am referring to
if (*A[i] > *A[j]) {
tmp = *A[i];
*A[i] = *A[j];
*A[j] = tmp;
} which should become
if (A[i] > A[j]) {
tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
You should check out the operators [] and *(dereference) precedence http://en.cppreference.com/w/c/language/operator_precedence
Now, to adapt to these changes (and further correct some code) your main would look like so:
int main(int argc, char *argv[])
{
int A[MAXVALUES], n;
do{
printf("n="); scanf("%d", &n);
}while(n < 0 || n > 20);
int i;
for(i = 0; i < n; ++i)
scanf("%d", &A[i]); //this will read your array from standard input
sort(A, n); //proper sort call
for(i = 0; i < n; ++i)
printf(" %d", A[i]);
printf("\n"); //add a newline to the output
return 0;
}
I have to display the following figure (The two triangles intercept) for a n given by the user, where n is odd. The figure is in this link: http://i.imgur.com/mQxarLz.jpg
*******
*****
***
*
*
***
*****
*******
I already wrote this code, but I don't know how to give the n, where n is odd. And my code doesn't compile; it says: "In the fifth row, syntax error before for".
#include <stdio.h>
int main (void) {
int n,i,k,m;
for(m=0;m<2;m++)
for (i=1;i<=n;i++){
if(m==0){
for(k = 1; k<=n-i; k++){
printf(" ");
}
}
}
for (k=1;k<2*i;k++){
printf("%s","*");
//printf("%d",i);
}
scanf("%d",&n);
for (k = 1; k<=i;k++)
for (k=1;k<(n-i)*2;k++)
for (i=1;i<=n;i++) {
printf("\n$");
}
return 0;
}
First, the answer to "how do I check whether an integer is odd": you simply divide by 2 and check if the remainder is 0 (even) or 1 (odd). In C and most related languages, this is what the modulo operator "%" does:
if ((n % 2) == 1) {
// The number is odd.
}
But you should make sure that you read your n right at the start, because in the code that you have submitted, n is read in your second "for" loop before you have actually written something to it. And that means, n contains garbage at that point.
Good programming is to solve problems in the most simple way you can find. This particular algorithm is really fundamental stuff, thus you shouldn't end up with anything much more complicated than this:
#include <stdio.h>
#include <stdbool.h>
void print_chars (char symbol, int n)
{
for(int i=0; i<n; i++)
{
printf("%c", symbol);
}
}
void print_triangle (int base_size, int height, bool pointing_up)
{
int star_count = pointing_up ? 1 : base_size;
for(int row = 0; row < height; row++)
{
int spaces = base_size - star_count;
print_chars (' ', spaces/2);
print_chars ('*', star_count);
print_chars (' ', spaces/2);
printf("%\n");
star_count += pointing_up ? 2 : -2;
}
}
int main (void)
{
print_triangle(7, 4, false);
print_triangle(7, 4, true);
}
Note that the above code will behave strange if the triangle's base isn't in sync with its height - I left that out intentionally, feel free to improve the program further with such.
#include <stdio.h>
void printAsterisk(int n, int length){
int i, slen = (length - n)/2;
for(i=0;i < slen;++i)
putchar(' ');
for(i=0;i < n;++i)
putchar('*');
putchar('\n');
}
/* non-recursive
void printTriangle(int n, int length){//n isn't required as an argument
int d= -2;
for(; n < length + 1; n += d){
if(n < 0) n += (d *= -1);
printAsterisk(n, length);
}
}
*/
void printTriangle(int n, int length){
if(n < 1) return;
printAsterisk(n, length);
printTriangle(n - 2, length);
printAsterisk(n, length);
}
int main(void){
int n;
do{
printf("input odd number:");
scanf("%d", &n);
}while(n % 2 == 0);
printTriangle(n, n);
return 0;
}