如何解决初始化从指针目标类型中丢弃“const”限定符
我有一个保存字符名称的数组结构。我想使用 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,input_file); // READ GPA
fread(&students[i]->age,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;
}
解决方法
变量 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);
}
,
代码中存在多个问题:
-
比较函数将指向常量对象的指针转换为指向非常量对象本身的指针,以及指向常量
student
对象的指针。不保留原始常量。定义应该是:const student_t * const *p1 = a; const student_t * const *p2 = b;
-
阅读循环应该在
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,input_file) != 1
|| fread(&students[i]->gpa,sizeof(students[i]->gpa),input_file) != 1
|| fread(&students[i]->age,sizeof(students[i]->age),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",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;
}
但是请注意,对数据使用二进制格式是有问题的:
- 各种类型的大小和表示形式可能会因系统而异。
- 二进制文件需要精确的规范并且不容易调试。
- 文本文件是用于交换的首选格式。它们易于阅读和编写。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。