arrayscfor-loopc-stringsfgets

Number index to array element


Task

Convert number to Chinese Pinyin. Minus sign is equal to "fu".

key-value

# num: pinyin

0: ling
1: yi
2: er
3: san
4: si
5: wu
6: liu
7: qi
8: ba
9: jiu

Code

#include <stdio.h>

int main() {
    char ipt[100];
    char py[10][6] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};

    fgets(ipt, 100, stdin);

    int i = 0;
    if (ipt[0] == '-') {
        printf("%s ", "fu");
        i++;
    }

    for (i; i < strlen(ipt); i++) {
        if (i < strlen(ipt) - 1)
            printf("%s ", py[ipt[i] - '0']);
        else
            printf("%s", py[ipt[i] - '0']);
    }
    return 0;
}

Tested case

I inputed 600, the output is "liu ling ling". I have tested some other numbers, and all of them seems good, but the checking website said I was wrong.


Solution

  • You've ignored the return value of fgets():

    fgets(ipt, 100, stdin);
    

    fgets() return a null pointer to indicate failure. Furthermore, fgets() include the newline in the input (if there's ample space). The simplest solution to strip it is:

    ipt[strcspn(ipt, "\n")] = 0;
    

    Now you can iterate through strlen() bytes like you originally were. Except that you don't need to call strlen() twice at each iteration. Simply cache the value:

    size_t ipt_len = strlen(ipt);
    

    Now, the code becomes:

    for (i; i < ipt_len; i++) {
        if (i < ipt_len - 1)
    

    But as you're already using strlen(), you can avoid the strcspn() call and do:

    size_t ipt_len = strlen(ipt); 
    
    if (ipt_len > 0 && name[ipt_len - 1] == '\n') {
        name[--ipt_len] = '\0';
    }
    

    You can also simplify the calls to printf():

    #if 0
    if (i < ipt_len - 1) 
        printf("%s ", py[ipt[i] - '0']);
    else
        printf("%s", py[ipt[i] - '0']);
    #else
    printf("%s%s", py[ipt[i] - '0'], i < ipt_len - 1 ? " " : "");
    #endif
    

    Or skip the whitespace altogether.

    Yet you've failed to verify whether the input actually consisted of digits and a minus sign fully. At least some rudimentary checking must be in place.

    Also note that the inner dimension of py:

    char py[10][6] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    

    should at most be 5, and not 6, because the longest string is "ling", which has size 5.

    Or you could use an array of char *s:

    static const char *const py[] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu" };
    

    Additionally, the outermost dimension is optional and can be elided, because it can be determined automatically by the compiler.