I'm trying to work a basic exercise in C and I do not understand what's happening. May I know why the "remarks" variable is not printed in this code using ternary operator?
#include <stdio.h>
int main(void) {
int grade1, grade2, grade3;
double average;
char remarks[15];
printf("Enter Grades of each subjects: \nEnglish: ");
scanf("%d", &grade1);
printf("Mathematics: ");
scanf("%d", &grade2);
printf("Programming: ");
scanf("%d", &grade3);
average = (grade1 grade2 grade3) / 3;
remarks[15] = (average > 74) ? "Passed":"Failed";
printf("\nAverage grade: %.2lf %s", average, remarks);
Basically, this exercise asks to get the average of 3 numbers(grade) and then either declare pass or fail depending on the result. One of the constraint is create and use the "remarks" variable using everything that I have studied so far -- basic printf(), scanf(), the use of ternary operator.
I'm not sure what's wrong with the code above. I'm getting the input correctly however the only thing that's getting printed out is the average.
When I modify the code and write it like this, it works just fine.
printf("\nAverage grade: %.2lf %s", average, average > 74 ? "Passed" : "Failed");
I think the issue is with re-assigning the variable remarks after getting all the grades. Am I doing something wrong?
EDIT: Added the placeholder %s in the first printf statement.
CodePudding user response:
Use
const char* remarks;
remarks = (average > 74) ? "Passed":"Failed";
printf("\nAverage grade: %.2lf", average, remarks);
or
char remarks[15];
strcpy( remarks, (average>74) ? "Passed" : "Failed" );
printf( "\nAverage grade: %.2lf", average, remarks);
They are different.
In the first case remarks
is a pointer, in the second case remarks
is a char array.
If you are wondering what is the difference between combinations of char pointers and const, look at this write up.
Godbolt link: https://godbolt.org/z/rz6bh4qzP
Writable pointer to a writable location
char* a1; // ok
char* a2 = nullptr; // ok
char* a3 = "Hello"; // error: ISO C forbids converting a string constant to 'char*'
a1 = nullptr; // ok
a1 = "Hello"; // error: ISO C forbids converting a string constant to 'char*'
a1[0] = 'x'; // ok
Writable pointer to a const location
const char* b1; // ok
const char* b2 = nullptr; // ok
const char* b3 = "Hello"; // ok
b1 = nullptr; // ok
b1 = "Hello"; // ok
b1[0] = 'x'; // error: assignment of read-only location
Const pointer to a writable location
char * const c1; // error: uninitialized const
char * const c2 = nullptr; // ok
char * const c3 = "Hello"; // error: ISO C forbids converting a string constant to 'char*'
c1 = nullptr; // error: assignment of read-only variable
c1 = "Hello"; // error: assignment of read-only variable
c1[0] = 'x'; // ok
Const pointer to a const location
const char * const f1; // error: uninitialized 'const f1'
const char * const f2 = nullptr; // ok
const char * const f3 = "Hello"; // ok
f1 = nullptr; // error: assignment of read-only variable
f1 = "Hello"; // error: assignment of read-only variable
f1[0] = 'x'; // error: assignment of read-only location
CodePudding user response:
You are assigning a const char *
to a char
(remarks[15]
). And that index is out of bounds, as C array indexing starts at 0
and for a 15 element array goes to 14
.
Use instead the following, which simply stores the remarks as a pointer to the correct string literal (const char *
).
char *remarks = (average > 74) ? "Passed" : "Failed";
CodePudding user response:
Two problems:
You're attempting to assign a string to a single array element,
remarks[15]
, instead of the entire array. Furthermore, since arrays in C are zero-based, the array indices range from0
to14
- attempting to write toremarks[15]
will write to memory outside of the array.You cannot use
=
to assign array contents, strings or otherwise. You must use thestrcpy
library function1, likestrcpy( remarks, average > 74 ? "Passed" : "Failed" )
. Or you'll have to assign individual array elements:remarks[0] = average > 74 ? 'P' : 'F'; remarks[1] = 'a'; remarks[2] = average > 74 ? 's' : 'i'; remarks[3] = average > 74 ? 's' : 'l'; remarks[4] = 'e'; remarks[5] = 'd'; remarks[6] = 0; // terminate the string
- Or
strncpy
, ormemcpy
, or similar.