C - Mixed Qsort with Struct (String and Double)
I have an almost complete code, need to Qsort some stuff, first I have array of integers, array of floats and then I have struct with char and double combined array. Need to somehow qsort them, but I am stuck.
Here is my code, I don't have problems with sorting integers and floats, but I can't complete struct sorting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncInt(const void *x, const void *y);
int ConparFuncFloat(const void *x, const void *y);
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/* void PrintIntegerArray(int *numbers, int len);
void PrintFloatArray(float *numbers, int len);
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
/* initialized variables to be used with functions */
int numArr1 = {15, 25, 3, 19, 22, 17, -54, 0, 9};
float numArr2 = {76.40f, 11.2f, 235.4f, 76.50f, 341.6f};
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
int numCount = sizeof(numArr1) / sizeof(int);
float floatCount = sizeof(numArr2) / sizeof(float);
double doubleCount = sizeof(struct product) / sizeof(double);
char charCount = sizeof(struct product) / sizeof(char);
while (1)
{
printf("nnSelect your action!nn");
printf("1. Sort integers (numArr1)n");
printf("2. Sort decimals (numArr2)n");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 1:
qsort(numArr1, (size_t)numCount, sizeof(int), ComparFuncInt);
for (int i = 0; i < numCount; printf("%3d", numArr1[i]), i++);
break;
case 2:
qsort(numArr2, (size_t)floatCount, sizeof(float), ConparFuncFloat);
for (int j = 0; j < floatCount; printf("%.2f ", numArr2[j]), j++);
break;
case 3:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
for (int k = 0; k < doubleCount; printf("%.2f ", prices[k].price), k++);
break;
case 4:
qsort(prices, (size_t)charCount, sizeof(char), ComparFuncStructName);
for (int l = 0; l < charCount; printf("%s", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncInt(const void *x, const void *y){
if(* (int*)x > *(int*)y) return 1;
else if(* (int*)x < *(int*)y) return -1;
else return 0;
}
int ConparFuncFloat(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
int ComparFuncStructName(const void *x, const void *y){
const char *pa = *(const char**)x;
const char *pb = *(const char**)y;
return strcmp(pa,pb);
}
int ComparFuncStructPrice(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
I want to do so as when user chooses 3, it goes and sorts array of PRICES under products by prices and if user chooses 4 it should sort by names, in both cases it should output both price and name, just difference in by what it was sorted.
c arrays loops struct qsort
add a comment |
I have an almost complete code, need to Qsort some stuff, first I have array of integers, array of floats and then I have struct with char and double combined array. Need to somehow qsort them, but I am stuck.
Here is my code, I don't have problems with sorting integers and floats, but I can't complete struct sorting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncInt(const void *x, const void *y);
int ConparFuncFloat(const void *x, const void *y);
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/* void PrintIntegerArray(int *numbers, int len);
void PrintFloatArray(float *numbers, int len);
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
/* initialized variables to be used with functions */
int numArr1 = {15, 25, 3, 19, 22, 17, -54, 0, 9};
float numArr2 = {76.40f, 11.2f, 235.4f, 76.50f, 341.6f};
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
int numCount = sizeof(numArr1) / sizeof(int);
float floatCount = sizeof(numArr2) / sizeof(float);
double doubleCount = sizeof(struct product) / sizeof(double);
char charCount = sizeof(struct product) / sizeof(char);
while (1)
{
printf("nnSelect your action!nn");
printf("1. Sort integers (numArr1)n");
printf("2. Sort decimals (numArr2)n");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 1:
qsort(numArr1, (size_t)numCount, sizeof(int), ComparFuncInt);
for (int i = 0; i < numCount; printf("%3d", numArr1[i]), i++);
break;
case 2:
qsort(numArr2, (size_t)floatCount, sizeof(float), ConparFuncFloat);
for (int j = 0; j < floatCount; printf("%.2f ", numArr2[j]), j++);
break;
case 3:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
for (int k = 0; k < doubleCount; printf("%.2f ", prices[k].price), k++);
break;
case 4:
qsort(prices, (size_t)charCount, sizeof(char), ComparFuncStructName);
for (int l = 0; l < charCount; printf("%s", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncInt(const void *x, const void *y){
if(* (int*)x > *(int*)y) return 1;
else if(* (int*)x < *(int*)y) return -1;
else return 0;
}
int ConparFuncFloat(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
int ComparFuncStructName(const void *x, const void *y){
const char *pa = *(const char**)x;
const char *pb = *(const char**)y;
return strcmp(pa,pb);
}
int ComparFuncStructPrice(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
I want to do so as when user chooses 3, it goes and sorts array of PRICES under products by prices and if user chooses 4 it should sort by names, in both cases it should output both price and name, just difference in by what it was sorted.
c arrays loops struct qsort
qsort(prices, ..., sizeof(double)is wrong, and bothComparFuncStructNameandComparFuncStructPriceneed to cast to a struct pointer. You need to pass the size of the struct to the function. A good way to avoid such mistakes is to writeqsort(array, num, sizeof *array, comparefn), similar toint *x = malloc(n * sizeof *x).
– Groo
Nov 22 '18 at 12:50
Possible duplicate of Need help using qsort with an array of structs. You could also use the Search box next time: stackoverflow.com/search?q=qsort+struct.
– Groo
Nov 22 '18 at 12:53
Step 1: changesizeof(array) / sizeof(type);-->sizeof array / sizeof array[0];
– chux
Nov 22 '18 at 12:56
add a comment |
I have an almost complete code, need to Qsort some stuff, first I have array of integers, array of floats and then I have struct with char and double combined array. Need to somehow qsort them, but I am stuck.
Here is my code, I don't have problems with sorting integers and floats, but I can't complete struct sorting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncInt(const void *x, const void *y);
int ConparFuncFloat(const void *x, const void *y);
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/* void PrintIntegerArray(int *numbers, int len);
void PrintFloatArray(float *numbers, int len);
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
/* initialized variables to be used with functions */
int numArr1 = {15, 25, 3, 19, 22, 17, -54, 0, 9};
float numArr2 = {76.40f, 11.2f, 235.4f, 76.50f, 341.6f};
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
int numCount = sizeof(numArr1) / sizeof(int);
float floatCount = sizeof(numArr2) / sizeof(float);
double doubleCount = sizeof(struct product) / sizeof(double);
char charCount = sizeof(struct product) / sizeof(char);
while (1)
{
printf("nnSelect your action!nn");
printf("1. Sort integers (numArr1)n");
printf("2. Sort decimals (numArr2)n");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 1:
qsort(numArr1, (size_t)numCount, sizeof(int), ComparFuncInt);
for (int i = 0; i < numCount; printf("%3d", numArr1[i]), i++);
break;
case 2:
qsort(numArr2, (size_t)floatCount, sizeof(float), ConparFuncFloat);
for (int j = 0; j < floatCount; printf("%.2f ", numArr2[j]), j++);
break;
case 3:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
for (int k = 0; k < doubleCount; printf("%.2f ", prices[k].price), k++);
break;
case 4:
qsort(prices, (size_t)charCount, sizeof(char), ComparFuncStructName);
for (int l = 0; l < charCount; printf("%s", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncInt(const void *x, const void *y){
if(* (int*)x > *(int*)y) return 1;
else if(* (int*)x < *(int*)y) return -1;
else return 0;
}
int ConparFuncFloat(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
int ComparFuncStructName(const void *x, const void *y){
const char *pa = *(const char**)x;
const char *pb = *(const char**)y;
return strcmp(pa,pb);
}
int ComparFuncStructPrice(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
I want to do so as when user chooses 3, it goes and sorts array of PRICES under products by prices and if user chooses 4 it should sort by names, in both cases it should output both price and name, just difference in by what it was sorted.
c arrays loops struct qsort
I have an almost complete code, need to Qsort some stuff, first I have array of integers, array of floats and then I have struct with char and double combined array. Need to somehow qsort them, but I am stuck.
Here is my code, I don't have problems with sorting integers and floats, but I can't complete struct sorting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncInt(const void *x, const void *y);
int ConparFuncFloat(const void *x, const void *y);
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/* void PrintIntegerArray(int *numbers, int len);
void PrintFloatArray(float *numbers, int len);
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
/* initialized variables to be used with functions */
int numArr1 = {15, 25, 3, 19, 22, 17, -54, 0, 9};
float numArr2 = {76.40f, 11.2f, 235.4f, 76.50f, 341.6f};
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
int numCount = sizeof(numArr1) / sizeof(int);
float floatCount = sizeof(numArr2) / sizeof(float);
double doubleCount = sizeof(struct product) / sizeof(double);
char charCount = sizeof(struct product) / sizeof(char);
while (1)
{
printf("nnSelect your action!nn");
printf("1. Sort integers (numArr1)n");
printf("2. Sort decimals (numArr2)n");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 1:
qsort(numArr1, (size_t)numCount, sizeof(int), ComparFuncInt);
for (int i = 0; i < numCount; printf("%3d", numArr1[i]), i++);
break;
case 2:
qsort(numArr2, (size_t)floatCount, sizeof(float), ConparFuncFloat);
for (int j = 0; j < floatCount; printf("%.2f ", numArr2[j]), j++);
break;
case 3:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
for (int k = 0; k < doubleCount; printf("%.2f ", prices[k].price), k++);
break;
case 4:
qsort(prices, (size_t)charCount, sizeof(char), ComparFuncStructName);
for (int l = 0; l < charCount; printf("%s", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncInt(const void *x, const void *y){
if(* (int*)x > *(int*)y) return 1;
else if(* (int*)x < *(int*)y) return -1;
else return 0;
}
int ConparFuncFloat(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
int ComparFuncStructName(const void *x, const void *y){
const char *pa = *(const char**)x;
const char *pb = *(const char**)y;
return strcmp(pa,pb);
}
int ComparFuncStructPrice(const void *x, const void *y){
if(* (float *)x > *(float *)y) return 1;
else if(* (float *)x < *(float *)y) return -1;
else return 0;
}
I want to do so as when user chooses 3, it goes and sorts array of PRICES under products by prices and if user chooses 4 it should sort by names, in both cases it should output both price and name, just difference in by what it was sorted.
c arrays loops struct qsort
c arrays loops struct qsort
edited Nov 22 '18 at 13:42
Aleksandre Sikharulidze
asked Nov 22 '18 at 12:45
Aleksandre SikharulidzeAleksandre Sikharulidze
225
225
qsort(prices, ..., sizeof(double)is wrong, and bothComparFuncStructNameandComparFuncStructPriceneed to cast to a struct pointer. You need to pass the size of the struct to the function. A good way to avoid such mistakes is to writeqsort(array, num, sizeof *array, comparefn), similar toint *x = malloc(n * sizeof *x).
– Groo
Nov 22 '18 at 12:50
Possible duplicate of Need help using qsort with an array of structs. You could also use the Search box next time: stackoverflow.com/search?q=qsort+struct.
– Groo
Nov 22 '18 at 12:53
Step 1: changesizeof(array) / sizeof(type);-->sizeof array / sizeof array[0];
– chux
Nov 22 '18 at 12:56
add a comment |
qsort(prices, ..., sizeof(double)is wrong, and bothComparFuncStructNameandComparFuncStructPriceneed to cast to a struct pointer. You need to pass the size of the struct to the function. A good way to avoid such mistakes is to writeqsort(array, num, sizeof *array, comparefn), similar toint *x = malloc(n * sizeof *x).
– Groo
Nov 22 '18 at 12:50
Possible duplicate of Need help using qsort with an array of structs. You could also use the Search box next time: stackoverflow.com/search?q=qsort+struct.
– Groo
Nov 22 '18 at 12:53
Step 1: changesizeof(array) / sizeof(type);-->sizeof array / sizeof array[0];
– chux
Nov 22 '18 at 12:56
qsort(prices, ..., sizeof(double) is wrong, and both ComparFuncStructName and ComparFuncStructPrice need to cast to a struct pointer. You need to pass the size of the struct to the function. A good way to avoid such mistakes is to write qsort(array, num, sizeof *array, comparefn), similar to int *x = malloc(n * sizeof *x).– Groo
Nov 22 '18 at 12:50
qsort(prices, ..., sizeof(double) is wrong, and both ComparFuncStructName and ComparFuncStructPrice need to cast to a struct pointer. You need to pass the size of the struct to the function. A good way to avoid such mistakes is to write qsort(array, num, sizeof *array, comparefn), similar to int *x = malloc(n * sizeof *x).– Groo
Nov 22 '18 at 12:50
Possible duplicate of Need help using qsort with an array of structs. You could also use the Search box next time: stackoverflow.com/search?q=qsort+struct.
– Groo
Nov 22 '18 at 12:53
Possible duplicate of Need help using qsort with an array of structs. You could also use the Search box next time: stackoverflow.com/search?q=qsort+struct.
– Groo
Nov 22 '18 at 12:53
Step 1: change
sizeof(array) / sizeof(type); --> sizeof array / sizeof array[0];– chux
Nov 22 '18 at 12:56
Step 1: change
sizeof(array) / sizeof(type); --> sizeof array / sizeof array[0];– chux
Nov 22 '18 at 12:56
add a comment |
2 Answers
2
active
oldest
votes
Change this:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
to:
qsort(prices, 6, sizeof(prices[0]), ComparFuncStructPrice);
since the array of structs has one size, regardless of whether you'd like to sort by name or price. Moreover, the size of every element of the array is equal to the size of the struct, regardless of whether you'd like to sort by name or price.
Similar for when sorting by names.
Also, your compare functions are wrong. First, you need to covert every void pointer to a struct. Then, you need to use the relevant field of the struct to compare.
For the prices comparison, use the less and more operators. If you simply subtract, you will get wrong results.
Putting everything together (and discarding the non-struct arrays), you get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/*
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
size_t pricesCount = sizeof prices / sizeof prices[0];
while (1)
{
printf("nnSelect your action!nn");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 3:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructPrice);
for (size_t k = 0; k < pricesCount; printf("%f ", prices[k].price), k++);
break;
case 4:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructName);
for (size_t l = 0; l < pricesCount; printf("%s ", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncStructName(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return strcmp(pa->name, pb->name);
}
int ComparFuncStructPrice(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return (pa->price > pb->price) - (pa->price < pb->price);
}
Output (if I choose to sort by name):
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
Bread Cucumber Juice Milk Orange Yogurt
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
return (pa->price - pb->price);returns anintconverted from adouble. In the unlikely case of prices beyondINT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works isreturn ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.
– Ian Abbott
Nov 22 '18 at 13:27
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
1
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
add a comment |
In the comparison functions, the pointers (x and y in your case) are pointers to elements of the array. If the array is an int, then it's a pointer to int (i.e. int *). If it's an array of structures, then they are pointers to the structure (like e.g. product *).
To access the members of the structure you of course needs to use the proper pointer-to-structure access, like e.g. the arrow operator ->.
It's also easier if you save the pointers in proper variables so you don't have to do all the casting all the time. In fact, if you want to use the passed data as pointers and not values there's no need to cast at all, because void * is implicitly convertible to almost any other pointer type (except pointers to functions).
So for your structure comparison function, you could do e.g.
int ComparFuncStructName(const void *x, const void *y){
const product *a = x;
const product *b = y;
return strcmp(a->name, b->name);
}
Or course, since you're sorting an array of structure, the element size of the array is the size of the structure, so you need to fix that too:
qsort(prices, charCount, sizeof prices[0], ComparFuncStructName);
Oh and you calculation of the number of elements in the structure is wrong as well. The formula is sizeof array / sizeof array[0]. Always. No matter the type of the array or its elements. The result of sizeof is always size_t, so you should use it as type for all sizeof operations as well.
So you need to do
size_t charCount = sizeof prices / sizeof prices[0];
On an unrelated and more stylistic note: Don't combine the printf call with the increment expression of the for loop. It will make the code harder to read, understand, follow and (most importantly) maintain.
Put all statements in the body of the loop instead:
for (int l = 0; l < charCount; l++)
printf("%s", prices[l].name);
You also don't need different iteration variables for the loops. They will be local for the loop inside their own scope, so you can reuse i for all the loops.
"so you don't have to do all the casting all the time." right, but then why the cast:const product *a = (const product *) x;?
– alk
Nov 22 '18 at 13:13
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
2
I meant why not just toconst product *a = x;?
– alk
Nov 22 '18 at 13:16
For completeness, maybe mention that OP's original comparison functions such asCompareFuncIntshould not cast away theconstqualifier.
– Ian Abbott
Nov 22 '18 at 13:20
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53431348%2fc-mixed-qsort-with-struct-string-and-double%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Change this:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
to:
qsort(prices, 6, sizeof(prices[0]), ComparFuncStructPrice);
since the array of structs has one size, regardless of whether you'd like to sort by name or price. Moreover, the size of every element of the array is equal to the size of the struct, regardless of whether you'd like to sort by name or price.
Similar for when sorting by names.
Also, your compare functions are wrong. First, you need to covert every void pointer to a struct. Then, you need to use the relevant field of the struct to compare.
For the prices comparison, use the less and more operators. If you simply subtract, you will get wrong results.
Putting everything together (and discarding the non-struct arrays), you get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/*
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
size_t pricesCount = sizeof prices / sizeof prices[0];
while (1)
{
printf("nnSelect your action!nn");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 3:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructPrice);
for (size_t k = 0; k < pricesCount; printf("%f ", prices[k].price), k++);
break;
case 4:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructName);
for (size_t l = 0; l < pricesCount; printf("%s ", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncStructName(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return strcmp(pa->name, pb->name);
}
int ComparFuncStructPrice(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return (pa->price > pb->price) - (pa->price < pb->price);
}
Output (if I choose to sort by name):
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
Bread Cucumber Juice Milk Orange Yogurt
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
return (pa->price - pb->price);returns anintconverted from adouble. In the unlikely case of prices beyondINT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works isreturn ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.
– Ian Abbott
Nov 22 '18 at 13:27
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
1
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
add a comment |
Change this:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
to:
qsort(prices, 6, sizeof(prices[0]), ComparFuncStructPrice);
since the array of structs has one size, regardless of whether you'd like to sort by name or price. Moreover, the size of every element of the array is equal to the size of the struct, regardless of whether you'd like to sort by name or price.
Similar for when sorting by names.
Also, your compare functions are wrong. First, you need to covert every void pointer to a struct. Then, you need to use the relevant field of the struct to compare.
For the prices comparison, use the less and more operators. If you simply subtract, you will get wrong results.
Putting everything together (and discarding the non-struct arrays), you get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/*
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
size_t pricesCount = sizeof prices / sizeof prices[0];
while (1)
{
printf("nnSelect your action!nn");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 3:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructPrice);
for (size_t k = 0; k < pricesCount; printf("%f ", prices[k].price), k++);
break;
case 4:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructName);
for (size_t l = 0; l < pricesCount; printf("%s ", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncStructName(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return strcmp(pa->name, pb->name);
}
int ComparFuncStructPrice(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return (pa->price > pb->price) - (pa->price < pb->price);
}
Output (if I choose to sort by name):
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
Bread Cucumber Juice Milk Orange Yogurt
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
return (pa->price - pb->price);returns anintconverted from adouble. In the unlikely case of prices beyondINT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works isreturn ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.
– Ian Abbott
Nov 22 '18 at 13:27
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
1
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
add a comment |
Change this:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
to:
qsort(prices, 6, sizeof(prices[0]), ComparFuncStructPrice);
since the array of structs has one size, regardless of whether you'd like to sort by name or price. Moreover, the size of every element of the array is equal to the size of the struct, regardless of whether you'd like to sort by name or price.
Similar for when sorting by names.
Also, your compare functions are wrong. First, you need to covert every void pointer to a struct. Then, you need to use the relevant field of the struct to compare.
For the prices comparison, use the less and more operators. If you simply subtract, you will get wrong results.
Putting everything together (and discarding the non-struct arrays), you get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/*
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
size_t pricesCount = sizeof prices / sizeof prices[0];
while (1)
{
printf("nnSelect your action!nn");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 3:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructPrice);
for (size_t k = 0; k < pricesCount; printf("%f ", prices[k].price), k++);
break;
case 4:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructName);
for (size_t l = 0; l < pricesCount; printf("%s ", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncStructName(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return strcmp(pa->name, pb->name);
}
int ComparFuncStructPrice(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return (pa->price > pb->price) - (pa->price < pb->price);
}
Output (if I choose to sort by name):
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
Bread Cucumber Juice Milk Orange Yogurt
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
Change this:
qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
to:
qsort(prices, 6, sizeof(prices[0]), ComparFuncStructPrice);
since the array of structs has one size, regardless of whether you'd like to sort by name or price. Moreover, the size of every element of the array is equal to the size of the struct, regardless of whether you'd like to sort by name or price.
Similar for when sorting by names.
Also, your compare functions are wrong. First, you need to covert every void pointer to a struct. Then, you need to use the relevant field of the struct to compare.
For the prices comparison, use the less and more operators. If you simply subtract, you will get wrong results.
Putting everything together (and discarding the non-struct arrays), you get:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
typedef struct product
{
double price;
char name[LEN];
} product;
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/*
void PrintStructArray(product *items, int len);
*/
int main(void)
{
unsigned option;
product prices = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
{1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
size_t pricesCount = sizeof prices / sizeof prices[0];
while (1)
{
printf("nnSelect your action!nn");
printf("3. Sort structures by pricen");
printf("4. Sort structures by namen");
printf("0. Exitn");
scanf("%u", &option);
switch (option)
{
case 3:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructPrice);
for (size_t k = 0; k < pricesCount; printf("%f ", prices[k].price), k++);
break;
case 4:
qsort(prices, pricesCount, sizeof(prices[0]), ComparFuncStructName);
for (size_t l = 0; l < pricesCount; printf("%s ", prices[l].name), l++);
break;
case 0:
exit(1);
break;
default:
printf("Only selections from 1 to 4 and 0 are acceptedn");
}
}
return EXIT_SUCCESS;
}
int ComparFuncStructName(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return strcmp(pa->name, pb->name);
}
int ComparFuncStructPrice(const void *x, const void *y){
const product* pa = (const product*) x;
const product* pb = (const product*) y;
return (pa->price > pb->price) - (pa->price < pb->price);
}
Output (if I choose to sort by name):
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
Bread Cucumber Juice Milk Orange Yogurt
Select your action!
3. Sort structures by price
4. Sort structures by name
0. Exit
edited Nov 22 '18 at 19:13
Jonathan Leffler
572k926851035
572k926851035
answered Nov 22 '18 at 12:54
gsamarasgsamaras
51.9k24107191
51.9k24107191
return (pa->price - pb->price);returns anintconverted from adouble. In the unlikely case of prices beyondINT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works isreturn ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.
– Ian Abbott
Nov 22 '18 at 13:27
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
1
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
add a comment |
return (pa->price - pb->price);returns anintconverted from adouble. In the unlikely case of prices beyondINT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works isreturn ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.
– Ian Abbott
Nov 22 '18 at 13:27
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
1
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
return (pa->price - pb->price); returns an int converted from a double. In the unlikely case of prices beyond INT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works is return ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.– Ian Abbott
Nov 22 '18 at 13:27
return (pa->price - pb->price); returns an int converted from a double. In the unlikely case of prices beyond INT_MAX, or the far more likely case of prices between 0 and 1, this won't work. A good trick to use that works is return ((pa->price > pb->price) - (pa->price < pb->price));, which will return -1, 0 or 1.– Ian Abbott
Nov 22 '18 at 13:27
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
It won't work @IanAbbott, that's why I changed it (most probably while you were writing your comment)! :)
– gsamaras
Nov 22 '18 at 13:28
1
1
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
Perfect, thanks for explanation now I understand it
– Aleksandre Sikharulidze
Nov 22 '18 at 13:41
add a comment |
In the comparison functions, the pointers (x and y in your case) are pointers to elements of the array. If the array is an int, then it's a pointer to int (i.e. int *). If it's an array of structures, then they are pointers to the structure (like e.g. product *).
To access the members of the structure you of course needs to use the proper pointer-to-structure access, like e.g. the arrow operator ->.
It's also easier if you save the pointers in proper variables so you don't have to do all the casting all the time. In fact, if you want to use the passed data as pointers and not values there's no need to cast at all, because void * is implicitly convertible to almost any other pointer type (except pointers to functions).
So for your structure comparison function, you could do e.g.
int ComparFuncStructName(const void *x, const void *y){
const product *a = x;
const product *b = y;
return strcmp(a->name, b->name);
}
Or course, since you're sorting an array of structure, the element size of the array is the size of the structure, so you need to fix that too:
qsort(prices, charCount, sizeof prices[0], ComparFuncStructName);
Oh and you calculation of the number of elements in the structure is wrong as well. The formula is sizeof array / sizeof array[0]. Always. No matter the type of the array or its elements. The result of sizeof is always size_t, so you should use it as type for all sizeof operations as well.
So you need to do
size_t charCount = sizeof prices / sizeof prices[0];
On an unrelated and more stylistic note: Don't combine the printf call with the increment expression of the for loop. It will make the code harder to read, understand, follow and (most importantly) maintain.
Put all statements in the body of the loop instead:
for (int l = 0; l < charCount; l++)
printf("%s", prices[l].name);
You also don't need different iteration variables for the loops. They will be local for the loop inside their own scope, so you can reuse i for all the loops.
"so you don't have to do all the casting all the time." right, but then why the cast:const product *a = (const product *) x;?
– alk
Nov 22 '18 at 13:13
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
2
I meant why not just toconst product *a = x;?
– alk
Nov 22 '18 at 13:16
For completeness, maybe mention that OP's original comparison functions such asCompareFuncIntshould not cast away theconstqualifier.
– Ian Abbott
Nov 22 '18 at 13:20
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
|
show 1 more comment
In the comparison functions, the pointers (x and y in your case) are pointers to elements of the array. If the array is an int, then it's a pointer to int (i.e. int *). If it's an array of structures, then they are pointers to the structure (like e.g. product *).
To access the members of the structure you of course needs to use the proper pointer-to-structure access, like e.g. the arrow operator ->.
It's also easier if you save the pointers in proper variables so you don't have to do all the casting all the time. In fact, if you want to use the passed data as pointers and not values there's no need to cast at all, because void * is implicitly convertible to almost any other pointer type (except pointers to functions).
So for your structure comparison function, you could do e.g.
int ComparFuncStructName(const void *x, const void *y){
const product *a = x;
const product *b = y;
return strcmp(a->name, b->name);
}
Or course, since you're sorting an array of structure, the element size of the array is the size of the structure, so you need to fix that too:
qsort(prices, charCount, sizeof prices[0], ComparFuncStructName);
Oh and you calculation of the number of elements in the structure is wrong as well. The formula is sizeof array / sizeof array[0]. Always. No matter the type of the array or its elements. The result of sizeof is always size_t, so you should use it as type for all sizeof operations as well.
So you need to do
size_t charCount = sizeof prices / sizeof prices[0];
On an unrelated and more stylistic note: Don't combine the printf call with the increment expression of the for loop. It will make the code harder to read, understand, follow and (most importantly) maintain.
Put all statements in the body of the loop instead:
for (int l = 0; l < charCount; l++)
printf("%s", prices[l].name);
You also don't need different iteration variables for the loops. They will be local for the loop inside their own scope, so you can reuse i for all the loops.
"so you don't have to do all the casting all the time." right, but then why the cast:const product *a = (const product *) x;?
– alk
Nov 22 '18 at 13:13
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
2
I meant why not just toconst product *a = x;?
– alk
Nov 22 '18 at 13:16
For completeness, maybe mention that OP's original comparison functions such asCompareFuncIntshould not cast away theconstqualifier.
– Ian Abbott
Nov 22 '18 at 13:20
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
|
show 1 more comment
In the comparison functions, the pointers (x and y in your case) are pointers to elements of the array. If the array is an int, then it's a pointer to int (i.e. int *). If it's an array of structures, then they are pointers to the structure (like e.g. product *).
To access the members of the structure you of course needs to use the proper pointer-to-structure access, like e.g. the arrow operator ->.
It's also easier if you save the pointers in proper variables so you don't have to do all the casting all the time. In fact, if you want to use the passed data as pointers and not values there's no need to cast at all, because void * is implicitly convertible to almost any other pointer type (except pointers to functions).
So for your structure comparison function, you could do e.g.
int ComparFuncStructName(const void *x, const void *y){
const product *a = x;
const product *b = y;
return strcmp(a->name, b->name);
}
Or course, since you're sorting an array of structure, the element size of the array is the size of the structure, so you need to fix that too:
qsort(prices, charCount, sizeof prices[0], ComparFuncStructName);
Oh and you calculation of the number of elements in the structure is wrong as well. The formula is sizeof array / sizeof array[0]. Always. No matter the type of the array or its elements. The result of sizeof is always size_t, so you should use it as type for all sizeof operations as well.
So you need to do
size_t charCount = sizeof prices / sizeof prices[0];
On an unrelated and more stylistic note: Don't combine the printf call with the increment expression of the for loop. It will make the code harder to read, understand, follow and (most importantly) maintain.
Put all statements in the body of the loop instead:
for (int l = 0; l < charCount; l++)
printf("%s", prices[l].name);
You also don't need different iteration variables for the loops. They will be local for the loop inside their own scope, so you can reuse i for all the loops.
In the comparison functions, the pointers (x and y in your case) are pointers to elements of the array. If the array is an int, then it's a pointer to int (i.e. int *). If it's an array of structures, then they are pointers to the structure (like e.g. product *).
To access the members of the structure you of course needs to use the proper pointer-to-structure access, like e.g. the arrow operator ->.
It's also easier if you save the pointers in proper variables so you don't have to do all the casting all the time. In fact, if you want to use the passed data as pointers and not values there's no need to cast at all, because void * is implicitly convertible to almost any other pointer type (except pointers to functions).
So for your structure comparison function, you could do e.g.
int ComparFuncStructName(const void *x, const void *y){
const product *a = x;
const product *b = y;
return strcmp(a->name, b->name);
}
Or course, since you're sorting an array of structure, the element size of the array is the size of the structure, so you need to fix that too:
qsort(prices, charCount, sizeof prices[0], ComparFuncStructName);
Oh and you calculation of the number of elements in the structure is wrong as well. The formula is sizeof array / sizeof array[0]. Always. No matter the type of the array or its elements. The result of sizeof is always size_t, so you should use it as type for all sizeof operations as well.
So you need to do
size_t charCount = sizeof prices / sizeof prices[0];
On an unrelated and more stylistic note: Don't combine the printf call with the increment expression of the for loop. It will make the code harder to read, understand, follow and (most importantly) maintain.
Put all statements in the body of the loop instead:
for (int l = 0; l < charCount; l++)
printf("%s", prices[l].name);
You also don't need different iteration variables for the loops. They will be local for the loop inside their own scope, so you can reuse i for all the loops.
edited Nov 22 '18 at 14:02
answered Nov 22 '18 at 12:54
Some programmer dudeSome programmer dude
303k25265426
303k25265426
"so you don't have to do all the casting all the time." right, but then why the cast:const product *a = (const product *) x;?
– alk
Nov 22 '18 at 13:13
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
2
I meant why not just toconst product *a = x;?
– alk
Nov 22 '18 at 13:16
For completeness, maybe mention that OP's original comparison functions such asCompareFuncIntshould not cast away theconstqualifier.
– Ian Abbott
Nov 22 '18 at 13:20
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
|
show 1 more comment
"so you don't have to do all the casting all the time." right, but then why the cast:const product *a = (const product *) x;?
– alk
Nov 22 '18 at 13:13
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
2
I meant why not just toconst product *a = x;?
– alk
Nov 22 '18 at 13:16
For completeness, maybe mention that OP's original comparison functions such asCompareFuncIntshould not cast away theconstqualifier.
– Ian Abbott
Nov 22 '18 at 13:20
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
"so you don't have to do all the casting all the time." right, but then why the cast:
const product *a = (const product *) x;?– alk
Nov 22 '18 at 13:13
"so you don't have to do all the casting all the time." right, but then why the cast:
const product *a = (const product *) x;?– alk
Nov 22 '18 at 13:13
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
@alk Maybe not a big difference in the example I show, but bigger in the numeric comparison functions. And you can't really do away with the casts, but you don't need to do it all the time.
– Some programmer dude
Nov 22 '18 at 13:15
2
2
I meant why not just to
const product *a = x;?– alk
Nov 22 '18 at 13:16
I meant why not just to
const product *a = x;?– alk
Nov 22 '18 at 13:16
For completeness, maybe mention that OP's original comparison functions such as
CompareFuncInt should not cast away the const qualifier.– Ian Abbott
Nov 22 '18 at 13:20
For completeness, maybe mention that OP's original comparison functions such as
CompareFuncInt should not cast away the const qualifier.– Ian Abbott
Nov 22 '18 at 13:20
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
@gsamaras There is enough information in this answer to allow OP to fix the prices comparison function without being spoon-fed.
– Ian Abbott
Nov 22 '18 at 13:37
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53431348%2fc-mixed-qsort-with-struct-string-and-double%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
qsort(prices, ..., sizeof(double)is wrong, and bothComparFuncStructNameandComparFuncStructPriceneed to cast to a struct pointer. You need to pass the size of the struct to the function. A good way to avoid such mistakes is to writeqsort(array, num, sizeof *array, comparefn), similar toint *x = malloc(n * sizeof *x).– Groo
Nov 22 '18 at 12:50
Possible duplicate of Need help using qsort with an array of structs. You could also use the Search box next time: stackoverflow.com/search?q=qsort+struct.
– Groo
Nov 22 '18 at 12:53
Step 1: change
sizeof(array) / sizeof(type);-->sizeof array / sizeof array[0];– chux
Nov 22 '18 at 12:56