clamismagic clamismagic - 22 days ago 15
C Question

Values always do not tally

I'm relatively new to C programming and I am trying to code a program that reads in a user's marks and assign a grade to the mark inputted.
I have used the

getline()
function to acquire user input. Below is my code.

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

int getMark();
void display(char grade);
char convert(int mark);

int getMark() {
do {
int marks;
char * buffer;
char characters;
size_t bufsize = 16;

buffer = (char *)malloc(bufsize * sizeof(char));
if( buffer == NULL) {
perror("Unable to allocate buffer");
exit(1);
}

printf("Enter the score (0 - 100)\nOr just press the enter key to quit ==> ");
characters = getline(&buffer, & bufsize, stdin);
int i;
long check;
for (i = 0; i < sizeof(buffer); i++) {
if (buffer[i] == '\n' && i != 0) {
buffer[i] = '\0';
}

if (isdigit(buffer[i]) || buffer[i] == '\0') {
check++;
}
}

if (buffer[0] == '\n') {
return -1;
} else if (check == strlen(buffer) - 1) {
marks = atoi(buffer);
} else {
printf("Please enter an integer.\n");
continue;
}

if (marks >= 0 && marks <= 100) {
return marks;
} else {
printf("Sorry, your marks can only be between 0 to 100.\n");
continue;
}

} while (1);
}

void display(char grade) {
printf("The grade for the input score is %c \n", grade);
}

char convert(int mark) {
mark /= 10;
char grade;

switch(mark) {
case 0:
case 1:
case 2:
case 3:
grade = 'F';
break;
case 4:
grade = 'E';
break;
case 5:
grade = 'D';
break;
case 6:
grade = 'C';
break;
case 7:
grade = 'B';
break;
case 8:
case 9:
case 10:
grade = 'A';
}

return grade;
}

int main() {
int marks;
for (;;) {
marks = getMark();
if (marks == -1) {
break;
}
display(convert(marks));
}

return 0;
}


When I press Enter, the program exits, as expected.
However, when an integer is entered, for example
12
, the output will always be
Please enter an integer.


Can anyone help me on this? Thanks!

Answer
char * buffer;
...
for (i = 0; i < sizeof(buffer); i++) {
    if (buffer[i] == '\n' && i != 0) {

sizeof(buffer) returns the size of a pointer to char (4 or 8 bytes depending on the architecture), not the length of the string, in consequence, you are reading outside of the bounds of the array when 12 is entered.

Change to strlen() or better yet, use the result of getline:

On success, getline() and getdelim() return the number of characters read, including the delimiter character, but not including the terminating null byte ('\0').

Comments