почему мой код получает это сообщение "Ошибка сегментации (дамп ядра)" - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь написать эту c программу в Linux, но когда я запускаю программу, она выполняет половину кода, а затем bash показывает это сообщение «Ошибка сегментации (дамп ядра)». Вот код:

#include<stdio.h>
#include<stdlib.h>

int main()
{   
    char stName[30];
    int info[3];
    int showinfo()
   {
    printf("The name of the student is %s\n",stName);
    printf("The age of the student is %d",info[0]);
    int i = 1;
    while(i<4)
    {
     printf("The marks in subject %d is %d",i,info[i]);
     i++;
    }
   }
    int getinfo()
   {
    printf("Enter name of the student: ");
    gets(stName);
    printf("enter the age of the student %s : ",stName);
    gets(info[0]);
    for(int i=1;i<4;i++)
    {
     printf("Enter the marks in subjet %d",i);
     gets(info[i]);
    }
    return 0;
   }
    getinfo();
    showinfo();
    
}

Результат выглядит следующим образом:

Enter name of the student: Keshav
enter the age of the student Keshav : 20
Segmentation fault (core dumped)

Ответы [ 2 ]

2 голосов
/ 06 августа 2020

У вас очень много мелких проблем. Сначала "ISO C forbids nested functions", вы должны объявить / определить void showinfo() и char *getinto() выше main(), а не в нем. Затем вы должны убедиться, что когда вы l oop, вы не пытаетесь писать за пределами ваших массивов. Далее см.: Почему gets () настолько опасен, что его никогда не следует использовать! Он настолько небезопасен и так подвержен атакам из-за переполнения буфера, он был полностью удален для библиотеки C11.

При записи showinfo(), которая представляет собой не что иное, как процедуру вывода, нет необходимости, чтобы эта функция возвращала значение. Измените тип возвращаемого значения на void, чтобы прояснить это. Поскольку теперь вы объявляете функции за пределами main(), вам нужно будет передать переменные, необходимые в этой функции, в качестве параметров, например,

#include <stdio.h>
#include <string.h>

#define MAXC 128   /* if you need a constant, #define one (or more) */
#define NFOC   4

void showinfo (const char *stName, int *info)
{
    printf ("\nThe name of the student is %s\n"
            "The age of the student is %d\n\n", stName, info[0]);
    
    for (int i = 1; i < NFOC; i++)
        printf ("  The marks in subject %2d is %2d\n", i, info[i]);
}

( примечание: вам нужен только single printf() для вывода обеих строк текста. Смежные буквенные символьные строки объединяются во время компиляции)

, а для getinfo(),

char *getinfo (char *stName, int *info)
{
    fputs ("Enter name of the student: ", stdout);
    if (fgets (stName, MAXC, stdin) == NULL)
        return NULL;
    stName[strcspn (stName, "\r\n")] = 0;   /* trim trailing \n from end of stName */
    
    printf ("enter the age of the student %s  : ", stName);
    if (scanf ("%d", &info[0]) != 1)
        return NULL;
    
    for (int i = 1; i < NFOC; i++) {
        printf ("Enter the marks in subjet %d : ", i);
        if (scanf ("%d", &info[i]) != 1)
            return NULL;
    }
    return stName;
}

Над массивами stName вместе с массив info передается как параметры функции, а также showinfo() выше. Здесь stName возвращается для удобства, позволяя при желании использовать функцию в списке переменных printf. Он возвращает NULL, чтобы указать на сбой при сборе входных данных.

main() теперь упрощается до:

int main (void)
{
    char stName[MAXC];
    int info[NFOC];
    
    getinfo (stName, info);
    showinfo (stName, info);
}

Пример использования / вывода

Запустив вашу программу и предоставив ввод при появлении запроса, вы получите следующий вывод:

$ ./bin/nested
Enter name of the student: John Q. Student
enter the age of the student John Q. Student  : 21
Enter the marks in subjet 1 : 88
Enter the marks in subjet 2 : 87
Enter the marks in subjet 3 : 92

The name of the student is John Q. Student
The age of the student is 21

  The marks in subject  1 is 88
  The marks in subject  2 is 87
  The marks in subject  3 is 92

Включить предупреждения

Всегда компилировать с включенными предупреждениями и не принимать код, пока он не скомпилируется без предупреждения . Чтобы включить предупреждения, добавьте -Wall -Wextra -pedantic в строку компиляции gcc/clang (также рассмотрите возможность добавления -Wshadow для предупреждения о теневых переменных). Для VS (cl.exe на windows) используйте /W3. Все остальные компиляторы будут иметь аналогичные параметры. Прочтите и поймите каждое предупреждение - затем go исправьте его. Они определят любые проблемы и точную линию, на которой они возникают. Вы можете многому научиться, слушая, что вам говорит ваш компилятор.

Посмотрите все и дайте мне знать, если у вас возникнут дополнительные вопросы.

0 голосов
/ 06 августа 2020

Может быть, вы хотите использовать get (& info [0]) not gets (info [0]). Но все еще есть ошибка.

   #include <stdio.h>

   char *gets(char *s);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...