#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct Student
{
char nume[20];
int grupa,nr_credite;
} S;
int cmpg(const void *a, const void *b);
int cmpc(const void *a, const void *b);
void ex();
int main()
{
ex(); //main program
return(0);
}
void ex() //sorting function
{
int n,i,c;
S st[100];
scanf("%d", &n);
for(i=0; i<n; i++)
scanf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite);
size_t no = sizeof(S)/sizeof(st->grupa);
size_t noo = sizeof(S)/sizeof(st->nr_credite);
qsort(st->grupa, no, sizeof(S), cmpg);
qsort(st->grupa, noo, sizeof(S), cmpc);
for(i=0; i<n; i++)
printf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite);
}
int cmpg(const void *a, const void *b)
{
struct Student *ia = (struct Student *)a;
struct Student *ib = (struct Student *)b;
return (int)(ia->grupa - ib->grupa);
}
int cmpc(const void *a, const void *b)
{
struct Student *ia = (struct Student *)a;
struct Student *ib = (struct Student *)b;
return (int)(ib->nr_credite - ia->nr_credite);
}
So the thing is I have some students in some different groups and they have a different number of credits. I want to use qsort to order them by group (ascending) and inside of each group to sort them by the number of credits(descending).
I have this code but it is stopping with this exit code: Process terminated with status -1073741819 (0 minute(s), 11 second(s)).
The problem comes from your calls of qsort. What qsort expects is the array to sort, the number of elements that should be sorted, the size of each element and the comparison function. So what you need is:
qsort(st, n, sizeof(S), cmpg);
qsort(st, n, sizeof(S), cmpc);
And your printf is also wrong:
for(i=0; i<n; i++)
printf("%s %d %d", st[i].nume, st[i].grupa, st[i].nr_credite);
BTW, you never test for errors which is bad:
if n>100, you will get an out of bond access on S
if there is an incorrect value in one the the answers, you will have read errors but still proceed with indeterminate values.
As noted in comments, this only fixes the error. But as qsort is not required to be a stable sort, two consecutive sorts may not produce what you want.
You want this:
void ex()
{
int n, i;
S st[100];
scanf("%d", &n);
for (i = 0; i<n; i++)
scanf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite);
qsort(st, n, sizeof(S), cmpg);
// ^ ^ ^
// | | |
// | | size of one element
// | |-- number of elements in array
// |-- address of first element of the array
//
qsort(st, n, sizeof(S), cmpc);
for (i = 0; i<n; i++)
printf("%s %d %d\n", st[i].nume, st[i].grupa, st[i].nr_credite); // removed &s
}
Related
*I am taking the size of array from user, the program runs perfectly when i declare int arr[n]; below the scanf in main but, it when i run following code is behaves differently each time, sometimes take more values, some times shows bus error. Even the value of n changes sometimes. *
//Code
#include <stdio.h>
void read_array(int arr[], int *n);
void print_array(int arr[], int *n);
int main() {
int n;
int arr[] = {};
printf("Enter array length ");
scanf("%d", &n);
printf("\nmain elements %d", n);
read_array(arr, &n);
printf("\nElements main %d", n);
print_array(arr, &n);
return 0;
}
void read_array(int arr[], int *n) {
int i;
printf("\n Elements R_A %d", *n);
printf("\nEnter elements");
for (i = 0; i < *n; i++) scanf("%d", &arr[i]);
}
void print_array(int arr[], int *n) {
int i;
printf("\n");
for (i = 0; i < *n; i++) printf("%d ", arr[i]);
printf("\n Elements P_A %d", *n);
}
When an array is declared without an explicit size, it size is taken to be the number of elements it is initialized with. So This:
int arr[]={};
Declares an array of size 0 which is invalid, and attempting to use it triggers undefined behavior.
int arr[] = {}; is a zero-length array (not supported by the standard) and you access it out of bounds.
If your compiler supports VLAs (variable length arrays), you could use one of those instead.
Example:
#include <stdio.h>
void read_array(int arr[], int *n);
void print_array(int arr[], int n); // no need to send in a pointer to n
int main() {
int n;
printf("Enter array length ");
if (scanf("%d", &n) != 1 || n < 1) return 1; // check that scanf succeeded
printf("\nmain elements %d", n);
int arr[n]; // a VLA of n elements
read_array(arr, &n);
printf("\nElements main %d", n);
print_array(arr, n);
return 0;
}
void read_array(int arr[], int *n) {
printf("\n Elements R_A %d", *n);
printf("\nEnter elements");
int i;
for (i = 0; i < *n; i++) {
if (scanf("%d", &arr[i]) != 1) break; // check that scanf succeeded
}
*n = i; // store the number of elements successfully read
}
void print_array(int arr[], int n) {
int i;
printf("\n");
for (i = 0; i < n; i++) printf("%d ", arr[i]);
printf("\n Elements P_A %d", n);
}
Write a program to enter id, name, and address to a structure array and sort them in ascending order on the basis of the name with the use of pointer?
I tried searching for so many questions in this forum, but none of them exactly helped me out. So this is my code:
#include<stdio.h>
struct student
{
char name[20], add[30];
int id;
};
int main()
{
struct student s[100];
struct student *sptr;
int i, j, temp, n;
char tempc[30];
sptr=&s;
printf("How many students do we have to register?");
scanf("%d",&n);
printf("Enter the id, name and address of the students and hit enter.");
for (i=0; i<n; i++)
{
scanf("%d%s%s",&sptr->id,&sptr->name,&sptr->add);
sptr++;
}
sptr=&s;
for(i=0; i<n; i++)
{
for(j=i+1;j<n;j++)
{
if(strcmp(s[i].name,s[j].name)>0)
{
strcpy(tempc,(sptr+i)->name);
strcpy(sptr->name,(sptr+j)->name);
strcpy((sptr+j)->name,tempc);
strcpy(tempc,sptr->add);
strcpy(sptr->add,(sptr+j)->add);
strcpy((sptr+j)->add,tempc);
temp=(sptr+j)->id;
sptr->id=(sptr+j)->id;
(sptr+j)->id=temp;
}
}
}
printf("The sorted form is:");
for (i=0; i<n; i++)
{
printf("%d%s%s",sptr->id,sptr->name,sptr->add);
sptr++;
}
}
If you're getting where I'm going, please help me out. And yeah I don't want to use any memory allocation functions or sizeof() function.
Simply use qsort like following:
int compare_student (const void * a, const void * b)
{
struct student *lhs = (struct student *)a;
struct student *rhs = (struct student *)b;
return strcmp( lhs->name, rhs->name) ;
}
// N = total number of students;
qsort (s, N, sizeof(struct student), compare_student);
I am trying to scanf values to an array from another function using pointer to pointer. Here's the code:
int initialize(int **arr, int count);
int main()
{
int count;
int *numbers;
scanf("Enter the amount of numbers to enter: %d", &count);
initialize(&numbers, count);
free(numbers);
return 0;
}
int initialize(int **arr, int count)
{
int i = 0;
*arr = calloc(count, sizeof(int));
while(i < count)
{
printf("Nr. %d: ", i + 1);
scanf("%d", &arr[i]);
i++;
}
return 0;
}
It allocates the memory correctly, however, there seems to be a problem inside scanf function in initialize so it crashes after reading in first 2 numbers. Could you help solve it?
arr is a pointer to pointer to int, so 1st make it a pointer to int (before using it like an array) by doing *arr.
So this
scanf("%d", &arr[i]);
should be
scanf("%d", &(*arr)[i]);
or its shorter equivalent
scanf("%d", *arr + i);
Unrelated, but in C it should be at least
int main(void)
Unrelated^2: Sizes and indexes in C best are defined using size_t (coming with stdlib.h).
So the relevant part of your code would look like this:
int main(void)
{
size_t count;
int *numbers;
scanf("Enter the amount of numbers to enter: %zu", &count);
...
int initialize(int **arr, size_t count)
{
size_t i = 0;
*arr = calloc(count, sizeof(int));
while (i < count)
...
Last not least the code misses error checking for the relevant functions:
scanf()
calloc()
Error checking (along with logging the errors) is debugging for free!
I'm trying to get my head around pointers and I'm trying to write a program which will swap two numbers using pointers. However, I'm getting the error as stated in the title. Here is my code:
//This program swaps two numbers using pointers
#include <stdio.h>
void swap(*val1, *val2);
int main() {
int num1, num2;
int *pNum1, *pNum2;
printf("Enter number 1:\n");
scanf("%d", &num1);
printf("Enter number 2:\n");
scanf("%d", &num2);
pNum1 = &num1;
pNum2 = &num2;
printf("Numbers not swapped: %d, %d\n", *pNum1, *pNum2);
swap(pNum1, pNum2);
return 0;
}
void swap(*val1, *val2) {
int temp;
temp = val1;
val1 = val2;
val2 = temp;
printf("Numbers swapped: %d, %d\n", *val1, *val2);
return;
}
void swap(*val1, *val2);
should be
void swap(int *val1, int *val2);
You should then pass
swap(&num1,&num2);
If you pass a pointer then you are passing a copy of it.You need to pass the address. No need of having pointers in the calling function you can directly pass the address of the variables.
void swap(int *p,int *q)
{
int t = *p;
*p = *q;
*q = t;
}
This program is supposed to take an array, and sort it from lowest to highest value. My program won't sort any values though. I believe the error is in the selectionSort. The values i and j are present in the function, I printed them out inside the function but they are not passed into the swap function. I tried making i and j pointers but it didn't work. I just have no clue on what to do next. Any help would be appreciated.
#include <stdio.h>
#define N 5
void selectionSort(int *a, int n);
int *findLargest(int *a, int n);
void swap(int *p, int *q);
int main(void)
{
int i;
int a[N];
printf("Enter %d numbers: ", N);
for (i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
selectionSort(a, N);
printf("In sorted order:");
for (i = 0; i < N; i++) {
printf(" %d", a[i]);
}
printf("\n");
return 0;
}
void selectionSort(int *a, int n)
{
int *p = a;
int i;
int j;
if (n == 1) {
return;
}
i = *(p+n-1);
j = *findLargest(a, n);
swap(&i, &j);
selectionSort(a, n - 1);
}
int *findLargest(int *a, int n)
{
int *p;
int *p_max = a;
for(p = a + 1; p < a + n - 1; p++) {
if ( *p > *p_max)
p_max = p;
}
return p_max;
}
void swap(int *p, int *q)
{
int temp = *(p-1);
*(p-1) = *q;
*q = temp;
}
The problem is in your call of swap: you swap the content of two local variables
int i;
int j;
... // Some other code, then
swap(&i, &j);
This has no effect on the original array. You should be passing p+n-1 and findLargest(a, n) directly, or store their results in pointers, not in ints:
swap(p+n-1, findLargest(a, n));
In addition, your swap is broken: rather than swapping the content of two pointers, it assumes that p points one element past the target location. This is a bad assumption to make in a general-purpose function, such as swap, and it also leads to undefined behavior in your program.
void swap(int *p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}