messerchainey
messerchainey

Reputation: 97

Toupper not working with char array

Thanks for your attention... I am really confused.. Why I cannot convert char type to uppercase with toupper when I gave the char an array... like this "char drh[1]"?

Here is my code.. This code is not finished yet.. I'm stuck in the midway.

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

using namespace std;
int main()
{
    char nama[50], gender[6], drh[1];
    int tahun_l, usia;
    float berat, tinggi, berat_i;

    printf("Masukkan Data Anda\n\n");
    // INPUT ZONE

    //First
    printf("Nama\t\t\t\t: ");
    scanf("%[^\n]", &nama);

    printf("Tahun Lahir (yyyy)\t\t: ");
    scanf("%d", &tahun_l);

    printf("Gol Darah (A/B/C)\t\t: ");
    scanf("%s", &drh);

    system("cls");

    //Second
    printf("Masukkan Data Anda\n\n");

    printf("Nama\t\t\t\t: %s\n", nama);
    fflush(stdin);

    printf("Tahun Lahir (yyyy)\t\t: %d\n", tahun_l);
    fflush(stdin);

    printf("Gol Darah (A/B/O)\t\t: %s\n", drh);
    drh = toupper(drh); //not working
    fflush(stdin);

    printf("Jenis Kelamin (Pria/Wanita)\t: ");
    scanf("%s", &gender);

    printf("Berat Badan (kg)\t\t: ");
    scanf("%f", &berat);

    printf("Tinggi Badan (cm)\t\t: ");
    scanf("%f", &tinggi);

    //FORMULA ZONE
    usia    = 2008 - tahun_l;
    berat_i = tinggi - 100 - (0.1 * (tinggi - 100));
    //OUTPUT ZONE
    printf("\n%s, berdasarkan data yang Anda masukkan,\n", nama);
    printf("Anda berjenis kelamin %s, saat ini Anda berusia %d tahun,\n", gender, usia);
    printf("Berat badan = %.2f kg, tinggi badan = %.2f cm, golongan darah = %s \n", berat, tinggi, drh);
    printf("\nBerat badan ideal adalah %.2f", berat_i);

    getche();
    return 0; 
}

Upvotes: 1

Views: 12344

Answers (3)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

The toupper function works on a single character, not on a string. If you need to convert the whole string to upper case, you need to use a loop:

for (char *p = drh ; *p ; *p = toupper(*p), p++)
    ;

However, your drh buffer does not have a sufficient length: it must have 2 characters to fit the null terminator:

char nama[50], gender[6], drh[2];
//  Add 1 char for terminator ^---- HERE

Moreover, since you know that drh is a single character, you can use

*drh = toupper(*drh);

Upvotes: 3

Marlon
Marlon

Reputation: 20312

The function toupper takes a single character and you are passing it an array of characters (yes, drh[1] is an array of one character). This line of code will never work with arrays:

drh = toupper(drh);

since you can't copy arrays like that. You are probably confusing a single char with a char[1]. You only have one option and that is to change the declaration of drh to char drh;.

And you will want to change this line of code:

scanf("%s", &drh);

to:

scanf("%c", &drh);

since you are reading a character not a string.

Upvotes: 2

zwol
zwol

Reputation: 140758

toupper works on individual characters, but you are trying to apply it to an entire array. The compiler should have complained about converting integers to pointers and back or something like that -- if it didn't, stop right now and turn warnings on.

To uppercase an entire "string" (nul-terminated character array) in C you have to loop over the characters yourself, like so:

for (char *p = drh; *p; p++)
  *p = toupper(*p);

That is the most idiomatic way to do this, but let me also write it a different way that may make it clearer what's going on:

char *p = drh;
while (*p != '\0')     // until we reach the end of the string
{
    *p = toupper(*p);  // upcase the character currently pointed to by 'p'
    p++;               // advance to the next character
}

EDIT: I failed to notice that you are passing a one-character array to scanf. That will inevitably corrupt your stack, because even if the user cooperates and types only one character, scanf will write two characters to the array (the character the user typed, and the obligatory NUL terminator). You need to make that char drh[2] if you want to use scanf("%s") to read one character. And even that won't help when (not if) the user types more than one character; the proper way to write this program would use fgets (or, better, getline) to read entire lines and then munch them by hand (i.e. not with sscanf). Basically in the long term you want to forget you ever heard of scanf or its relatives. I wouldn't blame you for wanting to solve one problem at a time, though.

Upvotes: 0

Related Questions