2014-09-07 3 views
-3

Я пытаюсь получить вход пользователя, записать ввод в файл, а затем использовать данные для структуры. Файл компилируется нормально, но после первого ввода я получаю сообщение об ошибке:Не удается найти причину ошибки сегментации (сбрасывание ядра) в C

$ gcc student.c -o student 
$ ./student 
Student First Name: 
alex 
Student Last Name: 
Segmentation fault (core dumped) 

Код:

/* student.h is to include the structure for stundent info */ 
#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 
    char sID[9]; 
    char firstN[30]; 
    char lastN[30]; 
    }student[100]; 

#include "student.h"  
int main() 
{ 
    FILE *sIf; 
    int i; 
    int num; 
    student *sI; 
    char *c; 
    char *b; 
    char *a; 

    sIf = fopen("student.txt", "a+"); 
    if(!sIf) 
    { 
     printf("File could not be opened\n\a\a"); 
     getchar(); 
     return -1; 
    } 
    { 
     printf("Student First Name: \n"); 
     scanf("%s", b); 
     printf("Student Last Name: \n"); 
     scanf("%s", a); 

     printf("Student ID Number: \n"); 
     scanf("%s", c); 

     fprintf(sIf, "%s, %s\t%s\n", a, b, c); 
    } 

    fclose(sIf); 
    return 0; 
} 
+7

Выделите пространство для 'a, b, c' или объявите их как массив. – haccks

+0

Вы должны скомпилировать с помощью 'gcc -Wall -g student.c -o student', и вам следует отлаживать использование' gdb student' –

+0

Нечетно, что у вас есть тип 'student', определенный вне заголовка' 'student.h" ' , Также странно, что вы определили его как тип массива. Это значительно усложнит его использование; тип 'sI' является указателем на массив, и иногда это нормально, скорее всего, это приведет к путанице. (Это также неиспользуемый код в показанном прогаме - просмотрите, как создать MCVE ([Как создать минимальный, полный и проверенный пример?] (Http://stackoverflow.com/help/mcve)) или SSCCE ([Short, Self-Contained, Correct Example] (http://sscce.org/)) - два имени и ссылки для одной идеи.) –

ответ

2
  1. Всегда использовать правильный отступ при кодировании, это делает код легко читать.
  2. Вы не выделяете память для своих char указателей a, b, c.
  3. Вместо scanf() использовать fgets(), чтобы принять входные строки.

Попробуйте этот фиксированный код (при необходимости, я добавил комментарии).

/* student.h is to include the structure for stundent info */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
//#include "student.h" 
typedef struct { 
    char sID[9]; 
    char firstN[30]; 
    char lastN[30]; 
    }student[100]; 
int main() 
{ 
    FILE *sIf; 
    student *sI;//Why are you using it? 
    char *ptr_pos; 
    //Fix 1 Allocate space for a, b and c 
    char *c=malloc(sizeof(char)*256); 
    if(c==NULL) 
    { 
     puts("Failed to allocate memory for variable c"); 
     exit(1); 
    } 
    char *b=malloc(sizeof(char)*256); 
    if(b==NULL) 
    { 
     puts("Failed to allocate memory for variable b"); 
     exit(1); 
    } 
    char *a=malloc(sizeof(char)*256); 
    if(a==NULL) 
    { 
     puts("Failed to allocate memory for variable a"); 
     exit(1); 
    } 

    sIf = fopen("student.txt", "a+"); 
    if(!sIf) 
    { 
     printf("File could not be opened\n\a\a"); 
     return EXIT_FAILURE; 
    } 
    printf("Student First Name: \n"); 
    //Accept string using fgets, it prevents from overflow 
    fgets(b,256,stdin); 
    b[strlen(b)-1]='\0'; //Remove \n from the input string 
    // Or you can use the following to remove `\n` from input string 
    //if((ptr_pos=strchr(b, '\n')) != NULL) 
    // *ptr_pos = `\0`; 


    printf("Student Last Name: \n"); 
    fgets(a,256,stdin); 
    a[strlen(a)-1]='\0'; 

    printf("Student ID Number: \n"); 
    fgets(c,256,stdin); 
    c[strlen(c)-1]='\0'; 

    fprintf(sIf, "%s, %s\t%s\n", a, b, c);  

    fclose(sIf); 
    //Free allocated memory 
    free(a); 
    free(b); 
    free(c); 

    return EXIT_SUCCESS; 
} 
+0

Лучше использовать буфер в стеке (избегать утечек памяти), а когда strlen равно 0 (пустой ввод), это приведет к повреждению стека. – mpromonet

+0

Где вы освобождаете память памяти? – Pixelchemist

+0

Проверьте распределения памяти; проверьте возврат из 'fgets()'; освободите выделенную память. И код еще не использует тип 'student', который, вероятно, также, так как' student * sI' является указателем на массив, который может вызвать путаницу. –

Смежные вопросы