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

char* genderfun(){
    char *gender;
    char g;
    printf("\n >>> enter your gender (M/F/T): ");
    //g = getc(stdin);
    scanf(" %c",&g);
    if(g == 'M'){
        gender = "Male";
    }else if(g == 'F'){
        gender = "Female";
    }else{
        gender = "Transgender";
    }
    return gender;
}

float percentagecalculator(){
    float math,physics,chemistry,english,other,percent;
    printf("\n >>> Enter maths marks: ");
    scanf("%f",&math);
    printf("\n >>> Enter english marks: ");
    scanf("%f",&english);
    printf("\n >>> Enter physics marks: ");
    scanf("%f",&physics);
    printf("\n >>> Enter chemistry marks: ");
    scanf("%f",&chemistry);
    printf("\n >>> Enter additional subject marks: ");
    scanf("%f",&other);
    percent = ((math+english+physics+chemistry+other)/500)*100;
    return percent;
}

void main(){
    char *name;
    char* genders;
    int age,count;
    float percent;
    printf(">>> Enter your name: ");
    scanf(" %c",&name);
    //fflush(stdin);
    printf("\n >>> Enter your age: ");
    scanf("%d",&age);
    genders = genderfun();
    percent = percentagecalculator();
    
    if(percent < 33){
        printf("\n name : %c \n age : %d \n gender : %c \n Percentage : %f \n Status : Failed",name,age,genders,percent);
    }else if(percent >= 33){
        printf("\n name : %c \n age : %d \n gender : %c \n Percentage : %f \n Status : Passed",name,age,genders,percent);
    }else{
        printf("\n Error");
    }
    
    
    
}

My code is not taking a name more than one character as input and if I try that it skips everything and programs ends and also the gender is not being returned but instead it prints very absurd values in console. Please help me fix this bug.

  • 1
    Try compiling with warnings enabled. If using GCC something like `gcc -W -Wall -pedantic` I can see right away you're trying to return a local variable, your scanf tries to write a character into a pointer and you don't check the scanf return value. – Zan Lynx Feb 06 '21 at 21:33
  • Always remember that in C, strings need to be stored in an array. Your `char *name` is not an array. It has no memory allocated for a string. Try `char name[80]`. Also `scanf` is not the best for reading strings. If you ever do use it for a string you would want `scanf("%79s", name)` Always be sure to limit the amount it will read or you will have a buffer overflow. I would try `fgets(name, 80, stdin)` which will read up to 79 characters or until a newline (the Enter key). – Zan Lynx Feb 06 '21 at 21:46
  • Huh. Oddly enough your `char *gender` that you return from a function is actually OK. Usually when I see those they are wrong. But since you are using literal strings the pointer is not pointing to the stack. – Zan Lynx Feb 06 '21 at 21:48
  • Thanks friend fgets have solved my name problem .I was using scanf because my college professor taught me so and I am very new to programming so I was using it. But gender problem is still to be solved. Maybe I should not use char and instead should ask users to enter numbers there ;). BTW thank you very much. – Meek Vishi Feb 07 '21 at 05:41

2 Answers2

0

Well, I've been reading your code and there are several problems. Here are the ones that I've found out:

  1. Return type of 'main' is not 'int'.
  2. In main: Unused variable 'count'
  3. Missing spacing and camel notation for function
  4. You're assuming to read string, but you are actually reading a char (e.g. the name, the creation of gender string, and so on).
  5. You're trying to insert a string, but reading a char, you pollute all your input buffer.
  6. You're using fflush(...). Please check here why you shouldn't use it: Using fflush(stdin)
  7. In order to use strings (or array of char) while reading dynamically names and assigning chars to an array of char, you need dynamic memory or at least VLA (in the following code, you will find the implementation with Dynamic Memory).
  8. In the 'percentage calculator' function you are assuming to take multiple values for each subject. Actually, you are taking only one mark for each subject.
  9. You are going wrong while reading a string. Here's how to properly do that: How to read string from keyboard using C?
  10. You are trying to print a char instead of a string in the final print.
  11. Please do a better naming of your variables and your functions.

I'm gonna attach here a working code for your question:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define stringSize 256

char * readGender() {
    fseek(stdin, 0, SEEK_END);
    char * gender = (char *) malloc(stringSize);
    char g;
    if (!gender) exit(EXIT_FAILURE);
    
    printf("\n >>> Enter your gender (M/F/T): ");
    g = getchar();
        
    if (g == 'M') {
        strcpy(gender, "Male");
    }else if(g == 'F') {
        strcpy(gender, "Female");
    }else {
        strcpy(gender, "Transgender");
    }
    gender = (char *) realloc(gender, strlen(gender) + 1);
    if (!gender) exit(EXIT_FAILURE);
    return gender;
}

float percentageCalculator() {
    float math, physics, chemistry, english, other, percent;
    printf("\n >>> Enter math mark: ");
    scanf("%f", &math);
    printf("\n >>> Enter english mark: ");
    scanf("%f", &english);
    printf("\n >>> Enter physics mark: ");
    scanf("%f", &physics);
    printf("\n >>> Enter chemistry mark: ");
    scanf("%f", &chemistry);
    printf("\n >>> Enter additional subject mark: ");
    scanf("%f", &other);
    percent = ((math + english + physics + chemistry + other) / 500) * 100;
    return percent;
}

int main() {
    char * gender;
    int age;
    float percentage;
    
    char *name = (char *) malloc(stringSize);
    if (!name) exit(EXIT_FAILURE);
    printf(">>> Enter your name: ");
    fgets(name, sizeof(stringSize - 1), stdin);
    
    name = (char *) realloc(name, strlen(name));
    if (!name) exit(EXIT_FAILURE);
    fseek(stdin, 0, SEEK_END);
    
    printf("\n >>> Enter your age: ");
    scanf("%d", &age);
    gender = readGender();
    percentage = percentageCalculator();
    
    if (percentage < 33) {
        printf("\n name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Failed\n", name, age, gender, percentage);
    } else if (percentage >= 33) {
        printf("\n name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Passed\n", name, age, gender, percentage);
    } else {
        printf("\n Error");
    }
    return 0;
}

Note that I've used fseek(...) as suggested here: How to clear input buffer in C? in order to read correctly char and integers together.

fseek(...) works on some systems; if not, then it is not surprising as nothing guarantees that it will work when standard input is an interactive device (or a non-seekable device like a pipe or a socket or a FIFO, to name but a few other ways in which it can fail).

If you need that it has to be portable, then check the link that I've placed before. Hope that it was helpful.

Next steps:

  • Adding user input error handling
  • Use a switch in 'readGender(...)' instead of the final triple if

Cheers, Denny

D. Caruso
  • 163
  • 1
  • 3
  • 11
0
#include<stdio.h>
#include<stdlib.h>
/*
  # Mistakes to avoid in future
  
  1. use fgets(name_of_inputVariable,size,stdin) instead of scanf
  2. use %s for strings rather than %c
  3. use *name_of_variable for the strings
  4. use fflush(stdin) only when program is skipping a certain step.
  5. use switch statements for the character stuff.
  
*/
char* getGender(){
    char *gender,g;
    printf(">>> enter a gender (m/f/t): ");
    scanf("%c",&g);
    switch(g){
        case 'm':
            gender = "Male";
            break;
        case 'f':
            gender = "Female";
            break;
        case 't':
            gender = "Transgender";
            break;
        default:
            gender = "prefer not to say";
    }
    return gender;
}

float percentageCalculator(){
    float math,physics,chemistry,english,other,percent;
    printf("\n >>> Enter maths marks: ");
    scanf("%f",&math);
    printf("\n >>> Enter english marks: ");
    scanf("%f",&english);
    printf("\n >>> Enter physics marks: ");
    scanf("%f",&physics);
    printf("\n >>> Enter chemistry marks: ");
    scanf("%f",&chemistry);
    printf("\n >>> Enter additional subject marks: ");
    scanf("%f",&other);
    percent = ((math+english+physics+chemistry+other)/500)*100;
    return percent;
}

void main(){
    char name[35];
    char *gender;
    int age,count;
    float percent;
    printf("\n >>> Enter your name: ");
    fgets(name,35,stdin); //fgets is way better than scanf. you can use exact value 35
    //scanf("%34s",&name); // scanf is a little buggy. you need to add one value less to prefent buffer overflow i.e. "%34s"
    //fflush(stdin); // fflush do solved problem as it took entire name but only printed first character in output. It's fixed via fgets now.
    printf("\n >>> Enter your age: ");
    scanf("%d",&age);
    fflush(stdin); // It was skipping gender ask step, so fflush fixed it by cleaning the overflow buffer. (fixed)
    gender = getGender(); // getGender have some problem. It prints very absurd values in output console. (fixed)
    percent = percentageCalculator(); // percentage calculator is working 100% fine. I got my accurate percentage and status lol ;)
    
    if(percent < 33){
        printf(" name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Failed",name,age,gender,percent);
    }else if(percent >= 33){
        printf(" name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Passed",name,age,gender,percent);
    }else{
        printf("\n Error");
    }
    
    
    
}

Here I have finally fixed all issues in my code and now my program is working correctly. Thanks for some ideas stackoverflow community.

  • You're welcome @MeekVishi. If you find the answer/comment helpful, please consider upvote them or mark the answer as helpful. – D. Caruso Feb 08 '21 at 10:20