#c #linux #struct #segmentation-fault #format-specifiers
#c #linux #структура #ошибка сегментации #спецификаторы формата
Вопрос:
Моя программа выдает несколько предупреждений, а затем выходит из строя. Кажется вероятным, что сбой связан с предупреждениями, но я их не понимаю. Вот мой код:
#include <stdio.h>
struct student {
char name[100];
int id;
char *department;
struct result {
float gpa;
char grade;
} res;
};
int main(void) {
struct student W[] = {{"Saud Farooqui",137,"Electronics",{3.05,'A'}},
{"Talha Farooqui",129,"Civil",{3.5,'A'}}};
printf("First student data isn%st%dt%st%ft%c",W[0].name,W[0].id,
W[0].department,W[1].res.gpa,W[0].res.grade);
printf("nSecond student data isn%st%dt%st%ft%c",W[1].name,W[1].id,
W[1].res.gpa,W[1].res.grade);
}
Компилятор напечатал эти предупреждения о спецификаторах формата во втором printf
:
foo.c:24:10: warning: format '%s' expects argument of type 'char *', but argument 4 has type 'double' [-Wformat=]
W[1].res.gpa,W[1].res.grade);
^
foo.c:24:10: warning: format '%f' expects argument of type 'double', but argument 5 has type 'int' [-Wformat=]
foo.c:24:10: warning: format '%c' expects a matching 'int' argument [-Wformat=]
Когда я попытался запустить программу, первая printf
напечатала строку, но вторая не удалась:
Segmentation fault (core dumped)
Что с этим не так? Как мне исправить предупреждения и сбой?
Комментарии:
1. что неясно в предупреждающих сообщениях? и не думаете ли вы, что ошибка segfault каким-то образом связана с вашим игнорированием предупреждений? предупреждения полезны, вы знаете. Вы принимаете это неправильно. Сначала исправьте предупреждения, и, возможно, ваш код будет выполняться именно так.
2. Я попытался немного изменить информацию, и теперь я думаю, что вопрос является более читаемым и достаточно хорошим вопросом.
Ответ №1:
Отсутствует аргумент для department
. Это очевидно, когда вы компилируете его с включенными предупреждениями ( -Wall
):
a.c:21:7: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘double’ [-Wformat=]
W[1].name, W[1].id, W[1].res.gpa, W[1].res.grade);
^
a.c:21:7: warning: format ‘%f’ expects argument of type ‘double’, but argument 5 has type ‘int’ [-Wformat=]
a.c:21:7: warning: format ‘%c’ expects a matching ‘int’ argument [-Wformat=]
Кроме того, ваши первые printf
отпечатки W[1].res
, которые, вероятно, должны быть W[0].res
.
Исправленная версия:
struct student W[] = {{"Saud Farooqui",137,"Electronics",{3.05,'A'}},
{"Talha Farooqui",129,"Civil",{3.5,'A'}}};
printf("First student data isn%st%dt%st%ft%c",
W[0].name, W[0].id, W[0].department, W[0].res.gpa, W[0].res.grade);
printf("nSecond student data isn%st%dt%st%ft%c",
W[1].name, W[1].id, W[1].department, W[1].res.gpa, W[1].res.grade);
Таким образом, ошибка сегментации вызвана попыткой интерпретировать W[1].res.gpa
как указатель на строку (соответствующую %s
спецификатору формата), т.е. const char *
.
Комментарии:
1. Разве этого не должно быть
W[1].department
?2. И хотя это не приводит к нарушению сегментации, не должно
W[1].res
бытьprintf
W[0].res
в первом случае? И не было бы лучше, если бы все это было сделано в виде цикла?3. Вы уверены, что операция не означала
W[1].res
?4. @msw, да, потому что первый ученик находится под первым индексом, т.Е.
0
5. проголосовали за закрытие, я забыл это сделать. Я согласен, что большинство вопросов содержат в себе некоторую тривиальность, но этот вопрос можно было бы решить исключительно путем чтения предупреждений, но иногда это сложно, поэтому на него стоит ответить. Здесь исправления довольно просты, это почти опечатка. Держитесь подальше от воскресных вопросов, за которые несколько раз голосовали с понижением, с надписью «студент» и тривиальных. В любом случае, у вас 2 голоса «за», так что все хорошо сбалансировано, вам это сходит с рук.