printTriangle with alphabets - c

#include <stdio.h>
int inputNumber();
void printTriangle(int size, char ch[]);
int main()
{
char arr_char[] = {'a','e','i','o','u'};
int number;
number = inputNumber();
printTriangle(number,arr_char);
return 0;
}
int inputNumber()
{
int size;
printf("Input Size: ");
scanf("%d",&size);
printf("===\nTriangle Size is %d\n===\n",size);
return size;
}
void printTriangle(int size, char ch[5])
{
int i,j;
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
if(j <= 4)
{
printf("%s ",ch[j]);
}
if(j > 4 )
{
printf("# ");
}
}
}
}
This is what it supposed to look like. And I'm confused as what I did wrong because it only work with inputNumber but not with printTriangle. a e i o u # # # please go easy on me since I'm kinda new to this.

The segmentation fault is caused by an incorrect format string (%s should be %c). The output format doesn't match expectations as the inner loop condition is wrong and you need a newline after you print each line (after inner loop):
#include <stdio.h>
#define LEN 5
int inputNumber() {
int size;
printf("Input Size: ");
scanf("%d",&size);
printf("===\nTriangle Size is %d\n===\n",size);
return size;
}
void printTriangle(int size, char ch[]) {
for(int i = 0; i < size; i++) {
for(int j = 0; j <= i; j++) {
printf("%c ", j < LEN ? ch[j] : '#');
}
printf("\n");
}
}
int main() {
char arr_char[LEN] = {'a','e','i','o','u'};
int number;
number = inputNumber();
printTriangle(number,arr_char);
return 0;
}
Consider using the type unsigned instead of int as negative size, row (i) and column (j) doesn't make sense.
Here is an alternatively implementation of printTriangle() that does a bit of work upfront to generate the last row, then use a prefix of that last row to print all rows:
void printTriangle(unsigned size, char ch[]) {
// use malloc if size is large (say >4k),
// or you don't want to use a variable length array (VLA)
char str[2 * size];
for(unsigned column = 0; column < size; column++) {
str[2 * column] = column < LEN ? ch[column] : '#';
str[2 * column + 1] = ' ';
}
for(unsigned row = 0; row < size; row++) {
printf("%.*s\n", 2 * row + 1, str);
}
}

Related

Sorting unique vectors in c

The program should eliminate any repeating digits and sort the remaining ones in ascending order. I know how to print unique digits but I don´t know how to create a new vector from them that i can later sort.
#include <stdio.h>
void unique(double arr[], int n) {
int i, j, k;
int ctr = 0;
for (i = 0; i < n; i++) {
printf("element - %d : ",i);
scanf("%lf", &arr[i]);
}
for (i = 0; i < n; i++) {
ctr = 0;
for (j = 0, k = n; j < k + 1; j++) {
if (i != j) {
if (arr[i] == arr[j]) {
ctr++;
}
}
}
if (ctr == 0) {
printf("%f ",arr[i]);
}
}
}
int main() {
double arr[100];
int n;
printf("Input the number of elements to be stored in the array: ");
scanf("%d", &n);
unique(arr, n);
}
You can always break a larger problem down into smaller parts.
First create a function that checks if a value already exists in an array.
Then create a function that fills your array with values. Check if the value is in the array before adding it. If it is, you skip it.
Then create a function that sorts an array. Alternatively, qsort is a library function commonly used to sort arrays.
This is far from efficient, but should be fairly easy to understand:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NUMS 256
int find(double *arr, size_t length, double val)
{
for (size_t i = 0; i < length; i++)
if (val == arr[i])
return 1;
return 0;
}
size_t fill_with_uniques(double *arr, size_t limit)
{
size_t n = 0;
size_t len = 0;
while (n < limit) {
double value;
printf("Enter value #%zu: ", n + 1);
if (1 != scanf("%lf", &value))
exit(EXIT_FAILURE);
/* if value is not already in the array, add it */
if (!find(arr, len, value))
arr[len++] = value;
n++;
}
return len;
}
int compare(const void *va, const void *vb)
{
double a = *(const double *) va;
double b = *(const double *) vb;
return (a > b) - (a < b);
}
int main(void)
{
double array[MAX_NUMS];
size_t count;
printf("Input the number of elements to be stored in the array: ");
if (1 != scanf("%zu", &count))
exit(EXIT_FAILURE);
if (count > MAX_NUMS)
count = MAX_NUMS;
size_t length = fill_with_uniques(array, count);
/* sort the array */
qsort(array, length, sizeof *array, compare);
/* print the array */
printf("[ ");
for (size_t i = 0; i < length; i++)
printf("%.1f ", array[i]);
printf("]\n");
}
Above we read values from stdin. Alternatively, fill_with_uniques could take two arrays, a source and a destination, and copy values from the former into the latter, only when they would be unique.
Remember to never ignore the return value of scanf, which is the number of successful conversions that occurred (in other words, variables assigned values). Otherwise, if the user enters something unexpected, your program may operate on indeterminate values.

Why do i get segmentation fault 11?

Why do I get segmentation fault 11? I get it quite often, and I know this time it is about the function. If anyone can help, please do, the code is down below! I am trying to make a program, that WITH A FUNCTION, can rearrange an array in ascending order and then print it in main in reverse order.
#include "stdio.h"
void changxr(int *counter, int *arrsize, int *j, int *arr[]);
int main()
{
int a, i, j, counter;
int arrsize;
int arr[100];
printf("pick an arraysize: \n");
scanf("%d", &arrsize);
printf("type %d numbers \n", arrsize);
for (counter = 0; counter < arrsize; counter++)
{
scanf("%d", &arr[counter]);
}
for (int c = arrsize - 1; c >= 0; c--)
{
printf("%d ", arr[c]);
}
changxr(&counter, &arrsize, &j, &arr[&counter]);
for (counter = arrsize - 1; counter >= 0; counter--)
{
printf("%d ", arr[counter]);
}
}
void changxr(int *counter, int *arrsize, int *j, int *arr[])
{
int a;
for (*counter = 0; *counter < *arrsize; *counter++)
{
for (*j = *counter + 1; *j < *arrsize; *j++)
{
if (*arr[*counter] > *arr[*j])
{
a = *arr[*counter];
*arr[*counter] = *arr[*j];
*arr[*j] = a;
}
}
}
}
New code:
#include "stdio.h"
void changxr(int arrsize, int *arr[]);
int main()
{
int a, i, j, counter;
int arrsize;
int arr[100];
printf("pick an arraysize: \n");
scanf("%d", &arrsize);
printf("type %d numbers \n", arrsize);
for (counter = 0; counter < arrsize; counter++)
{
scanf("%d", &arr[counter]);
}
for (int c = arrsize - 1; c >= 0; c--)
{
printf("%d ", arr[c]);
}
changxr(arrsize, &arr[counter]);
for (counter = arrsize - 1; counter >= 0; counter--)
{
printf("%d ", arr[counter]);
}
}
void changxr(int arrsize, int *arr[])
{
int a, counter, j;
for (counter = 0; counter < arrsize; counter++)
{
for (j = counter + 1; j < arrsize; j++)
{
if (*arr[counter] > *arr[j])
{
a = *arr[counter];
*arr[counter] = *arr[j];
*arr[j] = a;
}
}
}
}
This is what I got from debugging:
"Program received signal SIGSEGV, Segmentation fault.
0x0000555555555355 in changxr (arrsize=3, arr=0x0) at main.c:33
33 for(j=counter+1; j<arrsize; j++) { if(*arr[counter]>*arr[j]){
(gdb) continue"
You do not need two levels of indirection (int *arr[], *arr[counter], *arr[j]). When arr is passed to a function, it will decay to a pointer-to-its-first-element, or more simply, an int *.
&arr[counter] is also an int *, but it is the address of the array element one past the elements you've initialized. This would start your sorting function in the incorrect place.
Your program segfaults because it attempts to use this value as an int ** (int *[]).
gcc -Wall highlights this clearly:
prog.c: In function ‘main’:
prog.c:24:22: warning: passing argument 2 of ‘changxr’ from incompatible pointer type [-Wincompatible-pointer-types]
24 | changxr(arrsize, &arr[counter]);
| ^~~~~~~~~~~~~
| |
| int *
prog.c:3:32: note: expected ‘int **’ but argument is of type ‘int *’
3 | void changxr(int arrsize, int *arr[]);
| ~~~~~^~~~~
Things to do:
Simply pass the array and the length of the array to your function.
Use a single level of indirection in your function definition, and when accessing the array.
Use a variable-length array.
Use an auxiliary function for printing.
Declare variables when you need them, in the correct scope.
You should also consider checking the return value of scanf is the expected number of successful conversions.
The refactored code:
#include <stdio.h>
void changxr(int *a, size_t length)
{
for (size_t i = 0; i < length; i++) {
for (size_t j = i + 1; j < length; j++) {
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
void print_reverse(int *a, size_t length)
{
printf("[ ");
while (length--)
printf("%d ", a[length]);
printf("]\n");
}
int main(void)
{
size_t size;
printf("Pick an array length: ");
if (1 != scanf("%zu", &size) || size == 0) {
fprintf(stderr, "Invalid length input.\n");
return 1;
}
int array[size];
printf("Enter %zu numbers:\n", size);
for (size_t i = 0; i < size; i++) {
if (1 != scanf("%d", array + i)) {
fprintf(stderr, "Invalid integer input.\n");
return 1;
}
}
printf("Array (in reverse): ");
print_reverse(array, size);
changxr(array, size);
printf("Array, Sorted (in reverse): ");
print_reverse(array, size);
}

find first repeating name in multiple names entered by the user

There was a breakfast organised by social workers. There were many people in line to get the food packet. Find out first person who reappeared in line for food packet quickly.
Given
Adam, Binny, Sohail, Krishna , Mayank, Sohail, Adam
The output should be:
Sohail
I am unable to solve this in c language.
Please can somebody explain what to do?
This is my code:
#include<stdio.h>
int main()
{
int n,i,j;
char str[20][20];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",&str[i]);
}
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
if(str[i]==str[j]){
printf("%s\n",str[i]);
return 0;
}
}
}
return 0;
}
I am getting nothing in output.
It can give you some directions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct PersonInfo
{
char *name;
int number;
} person_info;
void check(person_info arr[], size_t size);
int main()
{
char *arr_debug[20] = {"Adam", "Binny", "Sohail", "Krishna", "Mayank", "Sohail", "Adam"};
int i = 0;
person_info arr[7];
size_t size = sizeof(arr)/sizeof(arr[0]);
person_info temp;
for (i = 0; i < size; i++) {
// scanf("%s", temp.name);
temp.name = arr_debug[i];
temp.number = i + 1; // start counting from 1
arr[i] = temp;
}
check(arr, size);
return 0;
}
void check(person_info arr[], size_t size) {
char *temp_name;
int nums[size]; // filled with 0s
int num = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (strcmp(arr[i].name, arr[j].name) == 0 && arr[i].number < arr[j].number) {
nums[num] = arr[j].number;
num++;
//store the number of the person
}
}
}
//find the earliest occurence
int earliest = nums[0];
for (int i = 1; i < size; i++) {
if (earliest > nums[i] && nums[i] != 0) {
earliest = nums[i];
}
}
//find the name associated to the number
for (int i = 0; i < size; i++) {
if (arr[i].number == earliest) {
temp_name = arr[i].name;
printf("%s \n", temp_name);
}
}
}

equating addresses of a 2d array and a 1d array in c

This prog is to accept an array of chars n compress them....(aaaabbbcc-->a4b3c2)....my prog is showing error at the point where im equating the addr of the 2d array to 1d array. This is my code:
/* size1 defined as 5 and size2 as 10.... (consts)*/
void compress(char data[SIZE1][SIZE2]);
int main()
{
char data[SIZE1][SIZE2];
printf("Enter a 5x10 matrix of characters:\n");
scanf("%c", &data);
compress(data[SIZE1][SIZE2]);
_getch();
return 0;
}
void compress(char data[SIZE1][SIZE2])
{
int hold[SIZE1*SIZE2];
int cnt = 0;
hold[SIZE1*SIZE2] = data[SIZE1][SIZE2];
for (int i = 0; i < (SIZE1*SIZE2); i++)
{
if (hold[i] == hold[i + 1])
{
cnt++;
continue;
}
else
{
printf("%c%d", hold[i], cnt);
}
}
}
This didn't work so I tried to use pointers:
void compress(char data[SIZE1][SIZE2])
{
int *hold[SIZE1*SIZE2];
int cnt = 0;
hold = data[SIZE1][SIZE2];
for (int i = 0; i < (SIZE1*SIZE2); i++)
{
if (*(hold+i) == *(hold+i+1))
{
cnt++;
}
else
{
printf("%c%d", *(hold+i), cnt);
}
}
}
I thought that the addrs of 2d arrays are stored linearly, hence they can be directly =to that of 1d.But the error says "'=':left operand must be an l-value".Im very new to pointers.Any help or corrections ....pls?
#include <stdio.h>
#define SIZE1 3
#define SIZE2 3
void compress(char data[SIZE1][SIZE2]);
int main(){
char data[SIZE1][SIZE2];
printf("Enter a %dx%d matrix of characters:\n", SIZE1, SIZE2);
for(int i=0;i<SIZE1;++i)
for(int j=0;j<SIZE2;++j)
scanf("%c", &data[i][j]);//aaaabbbcc
compress(data);
(void)getchar();
return 0;
}
void compress(char data[SIZE1][SIZE2]){
char *hold = &data[0][0];
int cnt = 1, size = SIZE1*SIZE2;
for (int i = 0; i < size; i++){
if (i < size -1 && hold[i] == hold[i + 1]){
cnt++;
//continue;
} else {
printf("%c%d", hold[i], cnt);//a4b3c2
cnt = 1;
}
}
}

Mergesort An Array of Strings in C

I'm trying to implement a merge sort for an array of strings entered from standard input, and am at a loss at what is wrong. Right now I'm facing a segmentation fault. How should I modify my code?
main() {
char temp;
int i = 0;
char Strings[NUM][LEN];
printf("Please enter %d strings, one per line:\n", NUM);
for (i; i < 25; i++) {
fgets(&Strings[i][0], LEN, stdin);
}
i = 0;
puts("\nHere are the strings in the order you entered:");
for (i; i < 25; i++) {
printf("%s\n", Strings[i]);
}
mergesort(Strings, NUM);
i = 0;
puts("\nHere are the strings in alphabetical order");
for (i; i < 25; i++) {
printf("%s\n", Strings[i]);
}
}
int mergesort(char list[NUM][LEN], int length) { // First part
mergesort_r(0, length, list);
return 0;
}
int mergesort_r(int left, int right, char list[NUM][LEN]) { // Overloaded portion
if (right - left <= 1) {
return 0;
}
int left_start = left;
int left_end = (left + right) / 2;
int right_start = left_end;
int right_end = right;
mergesort_r( left_start, left_end, list);
mergesort_r( right_start, right_end, list);
merge(list, left_start, left_end, right_start, right_end);
}
int merge(char list[NUM][LEN], int left_start, int left_end, int right_start, int right_end) {
int left_length = left_end - left_start;
int right_length = right_end - right_start;
char *left_half[left_length];
char *right_half[right_length];
int r = 0;
int l = 0;
int i = 0;
for (i = left_start; i < left_end; i++, l++) {
strcpy(left_half[l], list[i]);
}
for (i = right_start; i < right_end; i++, r++) {
strcpy(right_half[r], list[i]);
}
for (i = left_start, r = 0, l = 0; l < left_length && r < right_length; i++) {
if (strcmp(left_half[l], right_half[r]) < 0) {
strcpy(list[i], left_half[l++]);
} else {
strcpy(list[i], right_half[r++]);
}
}
for ( ; l < left_length; i++, l++) {
strcpy(list[i], left_half[l]);
}
for ( ; r < right_length; i++, r++) {
strcpy(list[i], right_half[r]);
}
return 0;
}
I'm not sure if it's that I'm passing in my array incorrectly, or maybe it's that I am not even executing swaps properly. I'm at my wits end with this and could use some advice.
should be
char left_half[left_length][LEN];
char right_half[right_length][LEN];
#include<stdio.h>
#include<stdlib.h>
#include<string.h> //To use the string functions like strcmp and strcpy
#define MAX 10 // This is the default size of every string
void Merge(char* arr[],int low,int mid,int high) //Merging the Array Function
{
int nL= mid-low+1;
int nR= high-mid;
char** L=malloc(sizeof(char *)*nL);
char** R=malloc(sizeof(char *)*nR);
int i;
for(i=0;i<nL;i++)
{
L[i]=malloc(sizeof(arr[low+i]));
strcpy(L[i],arr[low+i]);
}
for(i=0;i<nR;i++)
{
R[i]=malloc(sizeof(arr[mid+i+1]));
strcpy(R[i],arr[mid+i+1]);
}
int j=0,k;
i=0;
k=low;
while(i<nL&&j<nR)
{
if(strcmp(L[i],R[j])<0)strcpy(arr[k++],L[i++]);
else strcpy(arr[k++],R[j++]);
}
while(i<nL)strcpy(arr[k++],L[i++]);
while(j<nR)strcpy(arr[k++],R[j++]);
}
void MergeSort(char* arr[],int low,int high) //Main MergeSort function
{
if(low<high)
{
int mid=(low+high)/2;
MergeSort(arr,low,mid);
MergeSort(arr,mid+1,high);
Merge(arr,low,mid,high);
}
}
int main()
{
printf("\nEnter the size of the array desired: ");
int size; //This is the String array size
scanf("%d",&size);
char** arr= malloc(sizeof(char *)* size); //Creating required string array
printf("\nEnter the strings of the array: ");
int i;
for(i=0;i<size;i++)
{
arr[i]=malloc(sizeof(char)*MAX);
printf("\nEnter String: ");
scanf("%s",arr[i]);
}
MergeSort(arr,0,size-1);
printf("\nThe Sorted Array is: ");
for(i=0;i<size;i++)printf("%s ->",arr[i]);
return 0;
}
This is a Working solution to the same problem. Hope it Helps!
Cheers! :)
This solution of yours might give a memory error for long inputs or repeated executions. You need to free the allocated memory or not dynamically allocate it in the first place.
The latter is an easier option. What you can do is find the length of the longest string in the array of strings before hand and pass it as an argument to the merge sort and merge function.
Let's say that length is LEN.
Then instead of dynamically allocating memory for the L and R array, just declare it as:
char L[nL][LEN] and char R[nR][LEN].
It might take a slightly larger stack memory but avoids crashing the program.

Resources