lakam99
lakam99

Reputation: 605

Segmentation fault core dumped...?

I'm trying to accomplish this:

Write a program that accepts three user inputs: assignment mark, midterm mark, and final exam mark.

These inputs are of type float and should have values between 0 and 100.

The program should compute the final grade as a percentage and a letter grade.

• Final grades are computed as: Assignments 20%, Midterm 30%, Final exam 50%. Letter grades are computed as: A (final grade ≥ 80%), B (80 > final grade ≥ 70%), C (70 > final grade ≥ 60%), D (60 > final grade ≥ 50%), and F (50 > final grade).

The final grade and letter grade are displayed.

with the following code:

#include <stdio.h>

int checkMark(int);
float getMark();
float computeFinalGrade(float assign, float midterm, float finalExam, float finalGrade);
int computeLetterGrade(float);

int checkMark(int x)
{
    while(x<0 || x>100) //While x is a negative number:
    {
        printf("Invalid entry.Try again:");
        scanf("%d",&x);
    }

    if(x>0 && x<=100)//If x is a positive number:
        x=x;

    return x;
}

float getMark(void)
{
    float mark=0,assignMark=0,midMark=0,examMark=0,finalMark=0;
    char letterGrade;


    printf("Enter assignment grade:");
    scanf("%d",mark);

    checkMark(mark);
    assignMark=mark;

    printf("\nEnter midterm mark:");
    scanf("%f",&mark);

    checkMark(mark);
    midMark=mark;

    printf("\nEnter exam mark:");
    scanf("%f",&mark);

    checkMark(mark);
    examMark=mark;


    finalMark=computeFinalGrade(assignMark,midMark,examMark,finalMark);
    letterGrade=computeLetterGrade(finalMark);

    printf("The final grade for the course is %.1f, and the letter grade is %c.\n",finalMark,letterGrade);

    return 0;
}

float computeFinalGrade(float assign, float midterm, float finalExam, float finalGrade)
{
    assign=(float)0.2*assign;
    midterm=(float)0.3*midterm;
    finalExam=(float)0.4*finalExam;

    finalGrade=(float)assign+midterm+finalExam;
    return finalGrade;
}

int computeLetterGrade(float finalGrade)
{
    int grade;

        if(finalGrade>=80)
            grade=65;

        if(finalGrade<80)
            if(finalGrade>=70)
                grade=66;

        if(finalGrade<70)
            if(finalGrade>=60)
                grade=67;

        if(finalGrade<60)
            if(finalGrade>=50)
                grade=68;

        if(finalGrade<50)
            grade=70;

    return grade;
}

int main()
{
    getMark();

    return 0;
}

When I debug the program above and enter a negative number it gives me this:

Enter assignment grade:123
Segmentation fault (core dumped)

What am I doing wrong exactly?

Upvotes: 1

Views: 14295

Answers (4)

Adam Trhon
Adam Trhon

Reputation: 2935

If you are on linux, take a look at my answer here. It's about valgrind, a tool that helps debugging segfaults, memory leaks etc.

Upvotes: 2

Ptival
Ptival

Reputation: 9437

Some more remarks on your code:

int checkMark(int x)
{
    while(x<0 || x>100) //While x is a negative number:
    {
        printf("Invalid entry.Try again:");
        scanf("%d",&x);
    }

    if(x>0 && x<=100)//If x is a positive number:
        x=x;

    return x;
}

should rather be:

#define MIN_GRADE 0
#define MAX_GRADE 100

int checkMark(int x)
{
    while(x<MIN_GRADE || x>MAX_GRADE)
    {
        printf("Invalid entry.Try again:");
        scanf("%d",&x);
    }

    return x;
}

Notice that I:

  • removed useless comments

  • removed magic numbers (0 and 100)

  • removed a useless test (if you exit the while loop, then x is in {0, ..., 100}

  • allowed x to be equal to 0

  • removed an idempotent assignment (x=x doesn't do anything useful...)

Then:

float getMark(void)
{
    float mark=0,assignMark=0,midMark=0,examMark=0,finalMark=0;
    char letterGrade;

    printf("Enter assignment grade:");
    scanf("%d",mark);

^ As mentioned by others, you should use %f and &mark in this scanf.

    checkMark(mark);

^ Here, it should be mark = checkMark(mark); if you want the mark variable in this code to be updated. This is because the value of mark is passed to the function, not a reference to the variable mark. Another solution is to pass such a reference, but I don't think you're ready for this yet :)

    assignMark=mark;

    printf("\nEnter midterm mark:");
    scanf("%f",&mark);

    checkMark(mark);
    midMark=mark;

    printf("\nEnter exam mark:");
    scanf("%f",&mark);

    checkMark(mark);
    examMark=mark;

^ Same remarks for all these lines

    finalMark=computeFinalGrade(assignMark,midMark,examMark,finalMark);

^ Passing finalMark as a parameter here is completely useless. It should just be finalMark = computeFinalGrade(assignMark, midMark, examMark);, don't you think?

    letterGrade=computeLetterGrade(finalMark);

    printf("The final grade for the course is %.1f, and the letter grade is %c.\n",finalMark,letterGrade);

    return 0;
}

As mentioned just earlier, you don't need to pass some finalGrade value to computeFinalGrade, you should be okay with just:

float computeFinalGrade(float assign, float midterm, float finalExam)
{
    return 0.2*assign + 0.3*midterm + 0.4*finalExam; // this could even be a macro
}

Finally, in computeLetterGrade, you are doing a lot of redundant tests, and your control flow is messed up by this variable assignment, plus you should use a char rather than an int. Try this instead:

char computeLetterGrade(float finalGrade)
{
    if(finalGrade>=80) return 'A';
    // Since we did not return, necessarily finalGrade < 80
    if(finalGrade>=70) return 'B';
    if(finalGrade>=60) return 'C';
    if(finalGrade>=50) return 'D';
    // All other ifs failed, therefore finalGrade < 50
    return 'E';
}

You will probably need to fix some things I didn't mention, but at least you should be closer to your goals with some of these corrections.

Upvotes: 2

vidit
vidit

Reputation: 6451

Segmentation faults occur when your program tries to access a memory region outside the one assigned to your program. scanf() expects an address of the variable. In your code, you passed variable's value to scanf() instead of its address as pointed out by cnicutar.

scanf("%d",mark);

The mark variable is not initialized and has some random data, which is treated as a memory location by scanf and when it tries to write to that address... Segmentation fault occurs because you accessed a restricted memory. Also, mark is float variable and so you should use %f specifier..

scanf("%f", &mark);

Upvotes: 1

cnicutar
cnicutar

Reputation: 182639

This is your problem:

scanf("%d",mark);

You need to pass the address of the variable, and the specifier should be %f. Try:

scanf("%f", &mark);

Incidentally, there is a C FAQ about this.

Upvotes: 5

Related Questions