Array issue in C - c

I have an university project in C programming. I ran into a problem with the following task. My program should order numbers in two arrays. In the first array i must save (the biggest of every fifth element) and that is my problem. I am not sure how to make the loop which reads five elements compare them, take the biggest one, and then continue doing this with the other elements. I am hoping someone to help because I blocked.
#define A 100
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void show(int x[], int nx); //функция за показване на масивите
float vavedi(int x[], int nx); //функция, чрез която ръчно въвеждаме числата и ги обработваме
FILE* readFile(char* fname); //функция която чете файл и представя съдържанието му като масиви
int main()
{
int call, a = 0, b = 0, mode = 0, i = 0;
int check = 0;
char fail[A];
char* menu[] = {
"PROGRAM STARTED!",
"Enter an option:",
"1 : Write the numbers.",
"2 : Choose from a file.",
"0 : Exit."
};
do {
for (i = 0; i < 5; i++)
printf("%s\n", menu[i]);
check=scanf("%d", &mode);
if (check != 1)
printf("ERROR! Try again!");
switch (mode)
{
case 1: {
//в случай 1 числата се въведждат от потребителя
call = vavedi(a, b);
break;
}
case 2: {
//в случай 2 потребителя използва съществуващ файл
printf("Enter the path of the file you want to open:\n");
scanf("%s", fail);
call = readFile(fail);
if (call == NULL) {
printf("The file doesn't exist! Try again!\n");
}
break;
}
case 0:
break;
default:
{
printf("ERROR! Try again!\n");
}
}
} while (mode != 0);
printf("\nThe program ended!\n");
return 0;
}
void show(int x[], int nx)
{
int k;
for (k = 0; k < nx; k++)
{
printf("\n Element[%d]= %d", k, x[k]);
}
}
float vavedi(int x[], int nx)
{
int call=0;
int enter=0;
int imin, max;
int b[A], c[A];
int i, j, j1, count;
j = 0;
do {
printf("\nCount of the elements:");
scanf("%d", &count);
if (count <= 0 || count > 100)
printf("Invalid input! Try again!\n");
} while (count <= 0 || count > 100);
for (i = 0; i < count; i++)
{
printf("\nEnter an element:");
scanf("%d", &c[i]);
}
printf("\n");
return enter;
}

Update : Including header file mentioned by #pmg.
If i understand correctly, your problem is to find largest element for every five elements:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h> // Put this after your header files
..
.. //Rest of the code.
..
for (i = 0; i < count; i++)
{
printf("\nEnter an element:");
scanf("%d", &c[i]);
}
size_t size = ceil(count/5.0);
memset(b , INT_MIN , size);
for(int i = 0 ; i < count ; i++)
{
b[i/5] = b[i/5] > c[i] ? b[i/5] : c[i];
}
// Print b like this:
for(i = 0 ; i < size; i++)
printf("%d" , b[i] );
Let's see how this works for array of size 9. array's indices will go from 0 to 8 . If I divide each of them by 5, I get 0 for i = 0 to 4 and 1 for i = 5 to 8. Now we can take max over elements in buckets of 5. You seem to be a beginner, hope this helps you in creating better understanding.

The other problem is the following:
{
int c[A], b[A];
int i = 0, j = 0, k = 0, num;
FILE* fp= NULL; //указател за файл
fp = fopen(fname, "r");
if (fp)
{
while (fscanf(fp, "%d", &c[i]) != EOF)
i++;
num=i;
size_t size = ceil(num/5.0);
memset(b , INT_MIN , size);
for(i = 0 ; i < num ; i++)
{
b[i/5] = b[i/5] > c[i] ? b[i/5] : c[i];
}
printf("\nARRAY1:\n");
for(i = 0 ; i < size; i++)
{
buble(b, i);
printf(" Element[%d]=%1d\n", i, b[i]);
}
printf("\nARRAY2:");
buble(c, num);
show(c, num);
printf("\n");
}
fclose(fp);
return fp;
}
It doesn't calculate the rigth way.

Related

Reallocating my Memory doesnt work properly but i dont know what im doing wrong. Any idea?

code: (at //right here is the line that doesnt work)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void insert(int size, char *arr);
void swap(char *arr, int pos1, int pos2);
void printList(int size, char *arr);
int main()
{
int size = 0;
do
{
printf("Put in size of the list (Range[1;2^16-1]): ");
scanf(" %d", &size);
if (size < 0)
printf("Put in a correct length!\n");
} while (size <= 0);
printf("Put in ur List: ");
char buffer[size];
int errFlag;
do
{
errFlag = 1;
while (fgets(buffer, size + 2, stdin))
{
}
for (int i = 0; i < size; i++)
if (!isdigit(buffer[i]))
errFlag = 0;
if (errFlag == 0)
printf("Input failed try again:");
} while (errFlag == 0);
char *list = malloc(size*sizeof(char));
strcpy(list, buffer);
insert(size, list);
printList(size, list);
int input = 0;
do
{
printf("\nDo u want to add another element(0) or a list(1)? If u want to stop type (2): ");
scanf(" %d", &input);
if (input != 0 && input != 1 && input != 2)
printf("\nInput failed try again: ");
else if (input == 1)
{
int tempElem = 0;
printf("Input ur element: ");
scanf(" %d", &tempElem);
size++;
printf("%d", tempElem);
list = (char *)realloc(list, size + 1); //right here
list[size-1]=tempElem;
printf("New ");
insert(size, list);
printList(size, list);
}
} while (input != 0);
return 0;
}
void insert(int size, char *arr)
{
for (int i = 1; i < size; i++)
for (int j = i - 1; j >= 0; j--)
if (arr[j] > arr[j + 1])
swap(arr, j, j + 1);
else
j = 0;
}
void swap(char *arr, int pos1, int pos2)
{
char temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
}
void printList(int size, char *arr)
{
printf("ArrayList: ");
for (int i = 0; i < size; i++)
{
printf("[");
printf("%d", arr[i]-48);
printf("] ");
}
}
My code works properly until the reallocation, but i dont get an error. The programm just stops (VScode). I did some research but didnt find any solution.
Output:
Put in size of the list (Range[1;2^16-1]): 3
Put in ur List: 123
^Z (my input to stop f gets)
ArrayList: [1] [2] [3]
Do u want to add another element(0) or a list(1)? If u want to stop type (2): 1
Input ur element: 3
3
Then it stops. Normally i would expect: New ArrayList: [1] [2] [3] [4]

Selection sort not working as expected (C language)

I have to sort an array of structs with selection sort, after I read them from a file.txt.
My algorithm is not working as expected, but it always avoid to sort them and it print the struct in decreasing order.
Example of file.txt :
P0 "ANTONIO" 2000 4
P1 "BARTOLOMEO" 1995 6
P2 "CARLO" 2020 1
P3 "DEMETRIO" 1960 2
P4 "ETTORE" 1920 3
P5 "FRANCESCO" 1950 5
Input: 2 5 3 1 6 4
Output: 4 6 1 3 5 2
What am I doing wrong?
Code below:
#include <stdio.h>
#include <stdlib.h>
#define N 7
struct persona
{
char codice[10];
char nome[30];
int anno[10];
int reddito[10];
};
int main()
{
FILE* fp;
fp = fopen("Testo.txt", "r");
struct persona* persona = malloc(sizeof(struct persona) * N);
int i = 0;
int j = 0;
if (fp != NULL)
{
while (i < N-1)
{
fscanf(fp, "%s %s %s %s",
persona[i].codice,
persona[i].nome,
persona[i].anno,
persona[i].reddito);
i++;
}
}
else
{
perror("Errore");
}
fclose(fp);
for(i=0; i<N-2; i++)
{
int min = persona[i].reddito;
for(j=i+1; j<N-1; j++)
{
if(persona[j].reddito < persona[i].reddito)
{
min = persona[j].reddito;
}
persona[N] = persona[j];
persona[j] = persona[i];
persona[i] = persona[N];
}
}
for(i=0; i<N-1;i++)
{
printf("%s\t %s\t %s\t %s\n",
persona[i].codice,
persona[i].nome,
persona[i].anno,
persona[i].reddito);
}
}
You have 6 lines in the file, but you have defined N as 7. It should be updated to 6.
while (i < N-1)
You are reading the first N-2, that is, 5 lines from the file. The 6th line is not being read. Same goes for other loops in the code using N.
int anno[10];
int reddito[10];
You do not need integer array to read the numeric fields in file, an integer should suffice.
As mentioned by #WhozCraig in the comments, the selection sort algorithm is incorrect. Here's the updated code for reference:
#include <stdio.h>
#include <stdlib.h>
#define N 6
typedef struct persona
{
char codice[10];
char nome[30];
int anno;
int reddito;
} PERSONA;
int main()
{
FILE *fp;
if ((fp = fopen("file.txt", "r")) == NULL)
{
perror("\nFile not found");
exit(1);
}
PERSONA *persona = malloc(sizeof(struct persona) * N);
int i = 0, j;
while (i < N)
{ if (fscanf(fp, "%s %s %d %d", persona[i].codice, persona[i].nome, &persona[i].anno, &persona[i].reddito) == EOF) {
break;
}
i++;
}
fclose(fp);
PERSONA temp;
/* selection sort */
for (i = 0; i < N - 1; i++)
{
int jMin = persona[i].reddito;
for (j = i + 1; j < N; j++)
{
if (persona[j].reddito < persona[jMin].reddito)
{
jMin = j;
}
}
if (jMin != i)
{
temp = persona[i];
persona[i] = persona[jMin];
persona[jMin] = temp;
}
}
for (i = 0; i < N; i++)
{
printf("\n%s\t %s\t %d\t %d", persona[i].codice, persona[i].nome, persona[i].anno, persona[i].reddito);
}
}
Further improvements:
You could also calculate the number of lines in the file in the code instead of relying on a hardcoded value N.
The statement to check sets only the min only if this statement is true
if(persona[j].reddito < persona[i].reddito)
try using the qsort function
int cmpfunc (const void * a, const void * b) {
struct persona *p1 = (struct persona *)a;
struct persona *p2 = (struct persona *)b;
if(p1->reddito < p2->reddito) return -1;
if(p1->reddito > p2->reddito) return 1;
return 0;
}
and instead of the for loop, use
qsort(persona, N, sizeof(struct persona), cmpfunc);

Count repeated numbers in a file

So I'm having this file myFile.txt with the following numbers in it: 1 2 3 4 5 6 7 8 9 0 2 3 4 5 6 6 5 4 3 2 1. I'm trying to write a program that calculates how many times a number from 0 to 9 is repeated, so it would be printed out like that Number %d repeats %d times. Right now I'm stuck at printing out the n number of elements of that file, so in example, if I would like to calculate how many times the 15 first numbers repeat themselves, firstly I would print out those 15 numbers, then the number of times each number repeats. But when I'm trying to print out those 15 numbers, it prints me this: 7914880640-10419997104210821064219560-1975428800327666414848.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
int main() {
FILE *fp;
fp = fopen("myFile.txt", "r");
char c;
int n, i, count = 0;
for (c = getc(fp); c != EOF; c = getc(fp)) {
if (!(c == ' '|| c == '\n'))
count = count + 1;
}
printf("The amount of numbers is:%d\nTill which element of the list would you like to count the amount of the each element: \n", count);
scanf("%d", &n);
int a[n];
if (n <= count) {
for (i = 0; i < n; i++) {
fscanf(fp, "%d", &a[i]);
}
for (i = 0; i < n; i++) {
printf("%d", a[i]);
}
} else {
printf("Error");
}
fclose(fp);
return 0;
}
That's the final solution.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
int count_occur(int a[], char exist[], int num_elements, int value)
{
int i, count = 0;
for (i = 0; i<num_elements; i++)
{
if (a[i] == value)
{
if (exist[i] != 0)
return 0;
++count;
}
}
return(count);
}
int main()
{
int a[100],track[10];
FILE *fp;
fp = fopen("myFile.txt", "r");
char c,exist[20]= {0};
int n,i,num,count=0,k=0,eval;
for (c = getc(fp); c != EOF; c=getc(fp))
{
if (!(c==' '|| c=='\n'))
count=count+1;
}
rewind(fp);
printf("The amount of numbers is:%d\nTill which element of the list would you like to count the amount of the each element: \n", count);
scanf("%d", &n);
if (n<=count)
{
while(fscanf(fp, "%d", &num) == 1)
{
a[k] = num;
k++;
}
for (i=0; i<n; i++)
{
printf("%d ", a[i]);
}
}
else
{
printf("Error");
}
fclose(fp);
if (n<=count)
{
for (i = 0; i<n; i++)
{
eval = count_occur(a, exist, n, a[i]);
if (eval)
{
exist[i]=1;
printf("\nNumber %d was found %d times\n", a[i], eval);
}
}
}
return 0;
}

Can someone explain how i would open a file (containg a list of numbers) and then pass them though my selection sort algorithm?

So ive genertaed a list of random numbers (of varying size) that need to be sorted using selection sort, i have the selection sort algoruthm but im not sure how to open my file, read it and then pass it through my algorithm.
In my selection sort i have an array of number for temporary ue but they need to be replaced with the numbers from the file.
This is my selection sort code im using...
int main() {
int arr[10]={6,12,0,18,11,99,55,45,34,2};
int n=10;
int i, j, pos, s;
for (i = 0; i < (n - 1); i = i + 1) {
pos = i;
for (j = i + 1; j < n; j = j + 1) {
if (arr[pos] > arr[j])
pos = j;
}
if (pos != i) {
s = arr[i];
arr[i] = arr[pos];
arr[pos] = s;
}
}
for (i = 0; i < n; i = i + 1)
printf("%d\n", arr[i]);
return 0;
}
Here is a solution which reads the numbers from standard input. The first number in the input is the number of integers to read.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NEW_ARRAY(pointer, length) \
{ \
(pointer) = malloc((size_t) (length) * sizeof (pointer)[0]); \
if ((pointer) == NULL) { \
fprintf(stderr, "Allocating memory failed: %s\n", strerror(errno)); \
exit(EXIT_FAILURE); \
} \
}
void Read(int **numbers, int *numbersLength)
{
int count, i;
count = scanf("%d", numbersLength);
if ((count == 1) && (*numbersLength > 0)) {
NEW_ARRAY(*numbers, *numbersLength);
i = -1;
do {
i++;
count = scanf("%d", &(*numbers)[i]);
} while ((count == 1) && (i < *numbersLength - 1));
if (count != 1) {
fprintf(stderr, "Expected %d numbers but got only %d\n", *numbersLength, i);
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr, "Number of integers should be a positive integer\n");
exit(EXIT_FAILURE);
}
}
void Sort(int numbers[], int numbersLength)
{
/*your sorting logic here*/
}
void Print(const int numbers[], int numbersLength)
{
int i;
for (i = 0; i < numbersLength; i++) {
printf(" %d", numbers[i]);
}
}
int main(void)
{
int numbersLength;
int *numbers;
Read(&numbers, &numbersLength);
Sort(numbers, numbersLength);
Print(numbers, numbersLength);
putchar('\n');
free(numbers);
return 0;
}
I think you'll want fgetc and fopen: https://man7.org/linux/man-pages/man3/fopen.3.html, https://man7.org/linux/man-pages/man3/fgetc.3.html. If they have varying lengths you will probably also be looping until you read EOF, the end of file character. Hope this helps and good luck!

Replacing elements in an array

I have a problem thats giving me a huge ache.
This piece of code purpose is to fill up an array with integer values and at the same time defend against strings and etc....but it doesn't defend against duplicates, but tried I got to far as replacing the number with a new number for example
Enter 6 integers
1, 2, 2, 3, 4, 5
my code will let me replace that 2 at position 1 with another number. What I want it to do is not to repeat the same number again, for example please replace 2 at position 1. I dont want the user to enter 2 again... and I want to make it to double check the work the array if any repeating numbers exists thank you.
system("clear");
printf("\nEntering Winning Tickets....\n");
nanosleep((struct timespec[]){{1, 0}}, NULL);
system("clear");
char userInput[256];
char c;
int duplicationArray[6] = {-1, -1, -1, -1, -1, -1};
for (i = 0; i < 6; i++)
{
printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
fgets(userInput, 256, stdin);
if ((sscanf(userInput, "%d %c", &winningNumbers[i], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
printf("\nInvalid Input.\n") ;
nanosleep((struct timespec[]){{0, 350000000}}, NULL);
system("clear");
i = i - 1;
}
}
for (i = 0; i < 6 - 1; ++i)
{
min = i;
for (j = i+1; j < 6; ++j)
{
if (winningNumbers[j] < winningNumbers[min])
min = j;
}
temp = winningNumbers[i];
winningNumbers[i] = winningNumbers[min];
winningNumbers[min] = temp;
}
for (i = 0; i < 6; i++)
{
if (winningNumbers[i] == winningNumbers[i+1])
{
duplicationArray[i] = i;
duplicationCounter++;
}
else
{
duplicationCounter--;
}
}
if (duplicationCounter > -6)
{
for (i = 0; i < 6; i++)
{
int j, min, temp;
min = i;
for (j = i+1; j < 6; ++j)
{
if (duplicationArray[j] > duplicationArray[min])
min = j;
}
temp = duplicationArray[i];
duplicationArray[i] = duplicationArray[min];
duplicationArray[min] = temp;
}
for (i = 0; i < 6; i++)
{
if (duplicationArray[i] == -1)
{
zeroCounter++;
}
}
int resize = (6 - zeroCounter)+1;
for (i = 0; i <= resize; i++)
{
if (duplicationArray[i] == -1)
{
i++;
}
else if (duplicationArray[i] != -1)
{
system("clear");
printf("\nDuplicated numbers has been dected in your array. ");
printf("\nPlease replace the number %d at postion %d with another number: ", winningNumbers[duplicationArray[i]], duplicationArray[i]);
fgets(userInput, 256, stdin);
if ((sscanf(userInput, "%d %c", &winningNumbers[duplicationArray[i]], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
printf("\nInvalid Input.\n") ;
nanosleep((struct timespec[]){{0, 350000000}}, NULL);
system("clear");
i = i - 1;
}
}
}
duplicationCounter = 0;
for (i = 0; i < 6; i++)
{
if (winningNumbers[i] == winningNumbers[i+1])
{
duplicationArray[i] = i;
duplicationCounter++;
}
else
{
duplicationCounter--;
}
}
printf("%d, ", duplicationCounter);
}
#include <stdio.h>
#include <stdint.h>
#define DATA_SIZE 6
int main(void){
char userInput[256];
int inputNum, winningNumbers[DATA_SIZE];
uint64_t table = 0;
int i=0;
while(i<DATA_SIZE){
printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
fgets(userInput, sizeof(userInput), stdin);
if(sscanf(userInput, "%d", &inputNum) != 1 || inputNum <= 0 || inputNum >= 50)
continue;
uint64_t bit = 1 << inputNum;
if(table & bit)
continue;
table |= bit;
winningNumbers[i++] = inputNum;
}
for(i=0;i<DATA_SIZE;++i)
printf("%d ", winningNumbers[i]);
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 6
int inputNumberWithRangeCheck(const char *msg, const char *errMsg, int rangeStart, int rangeEnd){
char inputLine[256];
int n;
for(;;){
printf("%s", msg);
fgets(inputLine, sizeof(inputLine), stdin);
if(sscanf(inputLine, "%d", &n) != 1 || n < rangeStart || n > rangeEnd)
fprintf(stderr, "%s", errMsg);
else
return n;
}
}
int inputNumber(void){
return inputNumberWithRangeCheck(
"\nPlease enter the winning ticket number!(#'s must be between 1-49): ",
"Invalid Input.\n",
1,49);
}
int *inputArray(int *array, size_t size){
int i;
for(i=0;i<size;++i){
printf("\nInput for No.%d\n", i+1);
array[i] = inputNumber();
}
return array;
}
int **duplicateCheck(int *array, size_t size){
int **check, count;
int i, j;
check = malloc(size*sizeof(int*));
if(!check){
perror("memory allocate\n");
exit(-1);
}
//There is no need to sort the case of a small amount of data
//(Cost of this loop because about bubble sort)
for(count=i=0;i<size -1;++i){
for(j=i+1;j<size;++j){
if(array[i] == array[j]){
check[count++] = &array[i];
break;
}
}
}
check[count] = NULL;
if(count)
return check;
else {
free(check);
return NULL;
}
}
int main(void){
int winningNumbers[DATA_SIZE];
int **duplication;
int i, j;
inputArray(winningNumbers, DATA_SIZE);
while(NULL!=(duplication = duplicateCheck(winningNumbers, DATA_SIZE))){
for(i=0;i<DATA_SIZE;++i){
if(duplication[i]){
printf("\nyour input numbers : ");
for(j=0;j<DATA_SIZE;++j)
printf("%d ", winningNumbers[j]);
fprintf(stderr, "\nThere is duplicate. Please re-enter.\n");
*duplication[i] = inputNumber();
} else
break;
}
free(duplication);
}
for(i=0;i<DATA_SIZE;++i)
printf("%d ", winningNumbers[i]);
printf("\n");
return 0;
}

Resources