将阿拉伯数字(long long int)转换为C

时间:2019-06-05 12:13:38

标签: c type-conversion numbers

我想将一个数字(例如1024或2345787654)转换为英语单词,这样对于1024,它应该打印十二个等。

但是,我的代码给我分段错误。我尝试使用gdb运行它,但建议问题出在my_strcat函数内部。但是,我看不到此功能有任何问题。请帮助。

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

const char *digits[] = { NULL, "one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine " };
const char *tens[] = { NULL, "ten ", "twenty ", "thirty ", "forty ", "fifty ", "sixty ", "seventy ", "eighty ", "ninety " };
const char *teens[] = { "ten ", "eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen " };
const char *scales[] = { "", "thousand ", "million ", "billion " };

char *my_strcat ( char **dest, const char * src)
{
    char *tab = malloc ( sizeof ( char) * (strlen ( *dest) + strlen ( src) + 1));
    if ( NULL == tab)
        return NULL;
    strcpy ( tab, *dest);
    strcat ( tab, src);
    free ( *dest);
    *dest = malloc ( sizeof ( char) * ( strlen ( tab) + 1));
    strcpy ( *dest, tab);
    return tab;
}

char * LongToEnglish(unsigned long x)
{
    switch(x)
    {
    case 0:
        return "Zero";
    case 1:
        return "One";
    case 2:
        return "Two";
    case 3:
        return "Three";
    case 4:
        return "Four";
    case 5:
        return "Five";
    case 6:
        return "Six";
    case 7:
        return "Seven";
    case 8:
        return "Eight";
    case 9:
        return "Nine";
    case 10:
        return "Ten";
    case 11:
        return "Eleven";
    case 12:
        return "Twelve";
    case 13:
        return "Thirteen";
    case 14:
        return "Fourteen";
    case 15:
        return "Fifteen";
    case 16:
        return "Sixteen";
    case 17:
        return "Seventeen";
    case 18:
        return "Eighteen";
    case 19:
        return "Nineteen";
    case 20:
        return "Twenty";
    case 30:
        return "Thirty";
    case 40:
        return "Forty";
    case 50:
        return "Fifty";
    case 60:
        return "Sixty";
    case 70:
        return "Seventy";
    case 80:
        return "Eighty";
    case 90:
        return "Ninety";
    case 100:
        return "One Hundred";
    case 1000:
        return "One Thousand";
    case 1000000:
        return "One Million";
    case 1000000000:
        return "One Billion";
    }
    // less than 100
    for (long i = 1; i <= 9; i ++)
    {
        long j = i * 10;
        if ((x >= j) && (x < j + 10))
        {
            long r = x - j;

            if(r > 0)
                return my_strcat(my_strcat(*LongToEnglish(j), " "), LongToEnglish(r));
            else
                return my_strcat(*LongToEnglish(j), "");
        }
    }
    // less than 1000
    for (long i = 1; i <= 9; i ++)
    {
        long j = i * 100;
        if ((x >= j) && (x < j + 100))
        {
            long r = x - j;

            if(r > 0)
                return my_strcat(my_strcat(LongToEnglish(i), " Hundred "), LongToEnglish(r));
            else
                return my_strcat(LongToEnglish(i), " Hundred");
        }
    }
    // less than 10000
    for (long i = 1; i <= 9; i ++)
    {
        long j = i * 1000;
        if ((x >= j) && (x < j + 1000))
        {
            long r = x - j;
            if(r > 0)
                return my_strcat(my_strcat(LongToEnglish(i), " Thousand "), LongToEnglish(r));
            else
                return my_strcat(LongToEnglish(i), " Thousand");
        }
    }
    // Million
    for (long i = 1; i <= 9; i ++)
    {
        long j = i * 1000000;
        if ((x >= j) && (x < j + 1000000))
        {
            long r = x - j;
            if(r > 0)
                return my_strcat(my_strcat(LongToEnglish(i), " Million "), LongToEnglish(r));
            else
                return my_strcat(LongToEnglish(i), " Million");
        }
    }
    // Billion
    for (long i = 1; i <= 4; i ++)
    {
        long j = i * 1000000000;
        if ((x >= j) && (x < j + 1000000000))
        {
            long r = x - j;
            if(r > 0)
                return my_strcat(my_strcat(LongToEnglish(i), " Billion "), LongToEnglish(r));
            else
                return my_strcat(LongToEnglish(i), " Billion");
        }
    }
    // Divide the number into 3-digit groups from left to right
    char* output = "";
    long cnt = 0;
    while (x > 0)
    {
        long y = x % 1000;
        x /= 1000;
        if (y > 0)   // skip middle-chunk zero
        {
            char * t = "";
            if (cnt == 1) t = " Thousand ";
            if (cnt == 2) t = " Million ";
            if (cnt == 3) t = " Billion ";
            output = my_strcat(my_strcat(LongToEnglish(y), t), output);
        }
        cnt ++;
    }

    return (output);
}

char* numberToWords(int num)
{
    return LongToEnglish(num);
}

int main(int argc, char **argv)
{
    char *dst = NULL;
    dst = malloc ( sizeof ( char) * 10000000);

    unsigned long long n = 122334;
    dst = numberToWords(n);

    printf("%s", dst);
    free(dst);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您的代码中还有其他问题,我只说一个。当n=3中的输入为main时,numberToWords返回"Three",而您尝试调用free("Three"),等等。

有时您返回静态字符串,并尝试针对这种特殊情况释放它。

答案 1 :(得分:0)

该任务适用于成千上万始终相同的组。因此,您可以做的简单得多。 字符串处理可能已优化...

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

const char *digits[] = { NULL, "one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine ", "ten ", "eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen " };
const char *tens[] = { NULL, "ten ", "twenty ", "thirty ", "forty ", "fifty ", "sixty ", "seventy ", "eighty ", "ninety " };
const char *scales[] = { "", "thousand ", "million ", "billion " };

char *long2words(long x, int grp) {
    char *buf = malloc(4096), *bp;    
    int e,t,h;

    *buf='\0';
    e = x%10;
    t = (x/10)%10;
    h = (x/100)%10;
    x /=1000;
    if(x!=0) {
        strcat(buf, bp=long2words(x,grp+1));
        free(bp);
    }
    if(h!=0) {
        strcat(buf, digits[h]);
        strcat(buf,"hundred ");
    }
    if(t<2) strcat(buf, digits[t*10+e]);
    else {
        strcat(buf, tens[t]);
        strcat(buf, digits[e]);
    }
    strcat(buf, scales[grp]);

    return buf;
}
int main()
{
    printf(long2words(102410241024,0));

    return 0;
}