/*
https://stackoverflow.com/questions/53220084/proper-input-method-to-take-char-string-input-in-c/53221258#53221258
gcc array_struct_3.c &&./a.out
*/
#include<stdio.h>
#include<stdlib.h>
#define ROW 5 /* if you need a constant, #define one (or more) */
#define COL 64
typedef struct student_t
{
char name[COL];
int score;
} student_t;
int student_t_cmp_score(const void *x, const void *y)
{
struct student_t* const *ix = x;
struct student_t* const *iy = y;
return ((*ix)->score > (*iy)->score) - ((*ix)->score < (*iy)->score);
}
int main(void)
{
int n = 0;
// student_t student[ROW] = {{.name = ""}};
student_t *student[ROW];
puts("\n[note; press enter alone to end input]\n");
(student[n]) = malloc(sizeof(struct student_t));
for(;;){
char buf[COL];
fputs("Enter student name: ", stdout);
if (!fgets(buf, sizeof buf, stdin)) /* read/validate line */
break;
if(*buf == '\n') /* check for empty line */
break;
/* parse line into name and score - validate! */
if(sscanf(buf,"cs %d",student[n]->name, &student[n]->score) != 2)
{
fputs(" error: invalid input, conversion failed.\n",stderr);
continue;
}
n ;
student[n] = malloc(sizeof(struct student_t));
if(n== ROW){
fputs("\narray full - input complete.\n", stdout);
break;
}
}
printf("sizeof student: %zu\n", sizeof *student);
qsort(student, n, sizeof *student,student_t_cmp_score);
for(int i = 0; i < n; i )
printf("%-16s =\n",student[i]->name, student[i]->score);
return 0;
}
The above version will work. However, I try the following code then it's Segmentation fault. The line to make Segmentation fault is:
qsort(&student, n, sizeof *student,student_t_cmp_score);
.Since there is only 4 variable, so the only problem will be either &student or student_t_cmp_score for student_t_cmp_score, I just follow/copy other people code. Overall I don't know why it's Segmentation fault.
typedef struct student_t
{
char name[COL];
int score;
} student_t;
int student_t_cmp_score(const void *x, const void *y)
{
struct student_t* const *ix = x;
struct student_t* const *iy = y;
return ((*ix)->score > (*iy)->score) - ((*ix)->score < (*iy)->score);
}
int main(void)
{
int n = 0;
student_t student[ROW] = {{.name = ""}};
// student_t *student[ROW];
puts("\n[note; press enter alone to end input]\n");
// (student[n]) = malloc(sizeof(struct student_t));
for(;;){
char buf[COL];
fputs("Enter student name: ", stdout);
if (!fgets(buf, sizeof buf, stdin)) /* read/validate line */
break;
if(*buf == '\n') /* check for empty line */
break;
/* parse line into name and score - validate! */
if(sscanf(buf,"cs %d",student[n].name, &student[n].score) != 2)
{
fputs(" error: invalid input, conversion failed.\n",stderr);
continue;
}
n ;
// student[n] = malloc(sizeof(struct student_t));
if(n== ROW){
fputs("\narray full - input complete.\n", stdout);
break;
}
}
printf("sizeof student: %zu\n", sizeof *student);
qsort(&student, n, sizeof *student,student_t_cmp_score);
// qsort(student, n, sizeof *student,student_t_cmp_score);
for(int i = 0; i < n; i )
printf("%-16s =\n",student[i].name, student[i].score);
return 0;
}
I also tried use GDB via following command.
gdb ./a.out
(gdb) run
<segfault happens here>
(gdb) backtrace
error show in terminal:
sizeof student: 68
Program received signal SIGSEGV, Segmentation fault.
student_t_cmp_score (x=0x7fffffffdbe0, y=0x7fffffffdc24) at array_struct_3.c:22
warning: Source file is more recent than executable.
22 int student_t_cmp_score(const void *x, const void *y)
(gdb) backtrace
#0 student_t_cmp_score (x=0x7fffffffdbe0, y=0x7fffffffdc24) at array_struct_3.c:22
#1 0x00007ffff7dc6491 in msort_with_tmp (p=p@entry=0x7fffffffdb60, b=b@entry=0x7fffffffdab8,
n=n@entry=2) at ./stdlib/msort.c:123
#2 0x00007ffff7dc63a5 in msort_with_tmp (n=2, b=0x7fffffffdab8, p=0x7fffffffdb60)
at ./stdlib/msort.c:44
#3 msort_with_tmp (p=p@entry=0x7fffffffdb60, b=0x7fffffffdab8, n=n@entry=5) at ./stdlib/msort.c:52
#4 0x00007ffff7dc6992 in msort_with_tmp (n=5, b=<optimized out>, p=0x7fffffffdb60)
at ./stdlib/msort.c:44
#5 __GI___qsort_r (b=<optimized out>, n=<optimized out>, s=68, cmp=<optimized out>, arg=0x0)
at ./stdlib/msort.c:253
#6 0x0000555555555417 in main () at array_struct_3.c:60
CodePudding user response:
You changed from an array of pointers to a plain array. So your items are no longer pointers-to-struct, but struct items.
Change the callback function accordingly:
int student_t_cmp_score (const void *x, const void *y)
{
const struct student_t* ix = x;
const struct student_t* iy = y;
return (ix->score > iy->score) - (ix->score < iy->score);
}