ddp17
ddp17

Reputation: 41

Using Ternary Operator with strings in C

Trying to use ternary operator to assign string to remarks variable based on the average grade. But remark doesn't get assigned properly.

#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);

The program intends to get the average of 3 numbers(grade) and then either declare pass or fail depending on the result.

The program gets 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.

EDIT: Added the placeholder %s in the first printf statement.

Upvotes: 3

Views: 918

Answers (3)

Henrique Bucher
Henrique Bucher

Reputation: 4474

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.

Note this is C++ specific as C allows some of these:

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

Upvotes: 2

John Bode
John Bode

Reputation: 123448

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 from 0 to 14 - attempting to write to remarks[15] will write to memory outside of the array.

  • You cannot use = to assign array contents, strings or otherwise. You must use the strcpy library function1, like strcpy( 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
    


  1. Or strncpy, or memcpy, or similar.

Upvotes: 2

Chris
Chris

Reputation: 36496

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";

Upvotes: 2

Related Questions