提问人:collegecoder 提问时间:3/7/2021 最后编辑:collegecoder 更新时间:3/9/2021 访问量:2151
初始化从指针目标类型中丢弃“const”限定符
initialization discards ‘const’ qualifier from pointer target type
问:
我有一个包含字符名称的数组结构。我想使用 qsort 按字母顺序对它们进行排序,但是我不断收到一条错误消息,说“初始化从指针目标类型中丢弃'const'限定符”。我相信我的 cmpmi() 函数和 qsort 参数是正确的。任何帮助都非常感谢!
我的错误是:
gcc -std=gnu11 -Werror -Wall -o main main.c -lm -g
main.c: In function ‘compmi’:
main.c:18:25: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
const student_t **p1 = a;
^
main.c:19:25: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
const student_t **p2 = b;
^
cc1: all warnings being treated as errors
makefile:2: recipe for target 'main' failed
make: *** [main] Error 1
这是我的 qsort 函数:
int compmi(const void *a, const void *b)
{
const student_t **p1 = a;
const student_t **p2 = b;
return strcmp((*p1)->name, (*p2)->name);
}
法典:
int main(int argc, char **argv) {
unsigned numrecords;
int i = 0;
int length_multiplier = 1;
char *lettergrade;
//char *input = NULL;
//char *pItem;
student_t **students = NULL;
// OPENS THE FILE IN BINARY
FILE *input_file;
input_file = fopen("input.bin", "rb");
// READS THE NUMBER OF RECORDS
fread(&numrecords, sizeof(u_int32_t), 1, input_file);
// LOOPING THROUGH EACH ENTRY
for(i = 0; i <= numrecords; i++)
{
// ALLOCATES MEMORY
students = realloc(students, sizeof(student_t *) * length_multiplier);
students[i] = malloc(sizeof(student_t));
students[i]->name = malloc(sizeof(student_t)* 20);
fread(students[i]->name, sizeof(student_t), 20, input_file);//READ NAME
fread(&students[i]->gpa, sizeof(student_t), 1, input_file); // READ GPA
fread(&students[i]->age, sizeof(u_int32_t), 1, input_file);// READ AGE
length_multiplier++;
}
//SORTING WITH QSORT
qsort(*students, numrecords, sizeof(student_t *), compmi);
// PRINTING OUTPUT
for(i = 0; i < length_multiplier - 2 ; i++)
{
printf("%i of %d:\n", i + 1, numrecords);
printf("Name: %s\n", students[i]->name);
//printf("UPDATED GPA USE THIS: %.1f\n", students[i]->gpa);
printf("GPA: %.1f \n", students[i]->gpa);
printf("Age: %i\n", students[i]->age);
printf("\n");
}
// FREEING MEMORY
for(i = 0; i < length_multiplier; i++)
{
free(students[i]);
}
free(students);
fclose(input_file);
return 0;
}
答:
2赞
dbush
3/7/2021
#1
该变量指向限定类型,但不指向类型(但该类型指向的是)。您需要在 s 之间添加。a
const
p1
const
const
*
int compmi(const void *a, const void *b)
{
const student_t * const *p1 = a;
const student_t * const *p2 = b;
return strcmp((*p1)->name, (*p2)->name);
}
评论
0赞
collegecoder
3/7/2021
这修复了我的错误消息,但是当我尝试打印学生时,它们只是空的。返回条目后会发生什么情况?
0赞
CiaPan
3/8/2021
@collegecoder 按照这条评论说的去做:stackoverflow.com/questions/66510293/... 在 qsorting 之前验证您的数据是否正确读取,而不是抱怨它们不正确_after _ 某些处理。
1赞
chqrlie
3/7/2021
#2
代码中存在多个问题:
比较函数将指向常量对象的指针转换为指向非恒定对象本身的指针,将指向常量对象的指针转换为常量对象。没有保留原来的恒常性。定义应为:
student
const student_t * const *p1 = a; const student_t * const *p2 = b;
读取循环应该在 so you should use 而不是 .
i == numrecords
i < numrecords
i <= numrecords
大小不正确:应指定杆件类型的大小,而不是结构的大小。
fread
student_t
你传递给而不是数组指针。
*students
qsort
students
这是一个修改后的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student_t {
char *name;
float gpa;
int age;
} student_t;
int compmi(const void *a, const void *b) {
const student_t * const *p1 = a;
const student_t * const *p2 = b;
return strcmp((*p1)->name, (*p2)->name);
}
int main(int argc, char **argv) {
unsigned numrecords;
int i = 0;
char *lettergrade;
// OPENS THE FILE IN BINARY
FILE *input_file = fopen("input.bin", "rb");
if (input_file == NULL) {
fprintf(stderr, "cannot open input.bin\n");
return 1;
}
// READS THE NUMBER OF RECORDS
fread(&numrecords, sizeof(unsigned), 1, input_file);
// allocate the array directly, no need for realloc
student_t **students = malloc(sizeof(*students) * num_records);
if (students == NULL) {
fprintf(stderr, "allocation error\n");
return 1;
}
// LOOPING THROUGH EACH ENTRY
for (i = 0; i < numrecords; i++) {
// ALLOCATE MEMORY
if ((students[i] = malloc(sizeof(student_t))) == NULL
|| (students[i]->name = calloc(21, 1)) == NULL) {
fprintf(stderr, "allocation error\n");
return 1;
}
// READ NAME, GPA and AGE
if (fread(students[i]->name, 20, 1, input_file) != 1
|| fread(&students[i]->gpa, sizeof(students[i]->gpa), 1, input_file) != 1
|| fread(&students[i]->age, sizeof(students[i]->age), 1, input_file) != 1) {
fprintf(stderr, "error reading data for record %d / %d\n", i + 1, numrecords);
return 1;
}
}
fclose(input_file);
//SORTING WITH QSORT
qsort(students, numrecords, sizeof(*students), compmi);
// PRINTING OUTPUT
for (i = 0; i < numrecords; i++) {
printf("%i of %d:\n", i + 1, numrecords);
printf("Name: %s\n", students[i]->name);
//printf("UPDATED GPA USE THIS: %.1f\n", students[i]->gpa);
printf("GPA: %.1f\n", students[i]->gpa);
printf("Age: %i\n", students[i]->age);
printf("\n");
}
// FREEING MEMORY
for (i = 0; i < numrecords; i++) {
free(students[i]->name);
free(students[i]);
}
free(students);
return 0;
}
但请注意,对数据使用二进制格式是有问题的:
- 各种类型的大小和表示形式可能会因系统而异。
- 二进制文件需要精确的规范,并且不容易调试。
- 文本文件是交换的首选格式。它们易于阅读和书写。
评论
0赞
CiaPan
3/9/2021
您没有完成分配测试:在分配给“students[i]->name”之前,您测试了是否,但未测试是否为 non-null。students[i]->name != NULL
students[i]
0赞
chqrlie
3/9/2021
@CiaPan:好点子,答案修正了。鉴于该字段似乎具有固定长度,因此应将其定义为数组,而不是指向分配的内存,但 OP 没有提供结构定义,并且可能无法自由更改它。name
char name[21]
char *
评论
qsort(*students,...)
我认为这应该只是,而不是。您希望对整个指针数组进行排序,而不是对其第一个元素指向的“数组”进行排序。students
*students
for(i = 0; i <= numrecords; i++)
:看起来像一个差一的错误,应该是。i < numrecords