C代码生成两位数的整数转换成word的形式,是打印后输出的奇怪字符?[关闭]

lvmkulzt  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(115)

已关闭,此问题需要更focused。目前不接受答复。
**想改善这个问题吗?**更新问题,使其仅通过editing this post关注一个问题。

4天前关闭。
Improve this question
作为初学者,我正在用C编写一个简单的2位数到文本转换脚本。问题是,我有时会得到一个正常的预期输出,然后突然在Ubuntu(使用gcc)奇怪的符号。
打印消息示例如下所示:
你输入的数字是四十k d。
我不知道如何修复它,我对C非常陌生,所以我可能甚至不知道我在用那些分配函数做什么。请以任何方式帮助。
我得到的最好的结果是,我可以有一个没有null终止的字符串,但是如果我把字符串连接在一起,他们会自动在右上角有null终止吗?
我不知道是什么原因,所以我不知道如何解决它。但是,似乎有时在VS Code(MinGW编译器)上,我得到了完美的输出,而在Ubuntu上,它总是真实的,给予我奇怪的输出。
我尝试将变量answer的结尾强制为null-terminate(*(answer + 1)= '\0'),但它只是将奇怪的字符更改为新的奇怪字符。

bvn4nwqk

bvn4nwqk1#

你现在有一堆错误代码。作为一个问题,它缺乏重点。我建议你写一点代码。测试一下重复一遍一旦你厌倦了手工测试,就写一些单元测试。
我将与您分享一个工作实现,以便您可以了解如何构建解决方案。如果需要,可以将其用于单元测试。使用几个switch语句来确定word1word2是否满足您在其中一个注解中提到的要求。我故意把这个留给你做练习。
不要使用任意大小的50,而是使用最大的输出来调整字符串的大小,并使用snprintf()来避免错误时的缓冲区溢出。如你所知,上限大小只是使用一个常规的堆栈分配字符串,而不是处理malloc()free()每个循环迭代。
按照惯例,符号常量都是大写的。使用蛇的情况下,而不是 Camel 和蛇的情况下混合。

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

#define MIN_LARGE_NUMBER 20
#define MAX_WORD_SIZE sizeof "negative seventy eight"
// if s is the empty string return "" otherwise " "
#define sep(s) " " + !*(s)

const char *small_numbers[] = {
    "zero",
    "one",
    "two",
    "three",
    "four",
    "five",
    "six",
    "seven",
    "eight",
    "nine",
    "ten",
    "eleven",
    "twelve",
    "thirteen",
    "fourteen",
    "fifteen",
    "sixteen",
    "seventeen",
    "eighteen",
    "nineteen",
};

const char *large_numbers[] = {
    "twenty", // MIN_LARGE_NUMBER
    "thirty",
    "forty",
    "fifty",
    "sixty",
    "seventy",
    "eighty",
    "ninety"
};

char *get_number_word(int number, char word[MAX_WORD_SIZE]) {
    const char *negative;
    if(number < 0) {
        negative = "negative";
        number *= -1;
    } else {
        negative  = "";
    }

    // number - MIN_LARGE_NUMBER deals with the offset in the table,
    // and / 10 converts it to an array index.  The alternative would
    // be to leave the two two entries empty with [2] = "tweenty",
    // "thirty", ...
    const char *word1 = number >= MIN_LARGE_NUMBER ?
        large_numbers[(number - MIN_LARGE_NUMBER) / 10] :
        "";
    // for large numbers we only want the 2nd word if the last digit
    // is non-zero.
    const char *word2 = number < MIN_LARGE_NUMBER ?
        small_numbers[number] :
        number % 10 ?
            small_numbers[number % 10] :
            "";

    snprintf(word, MAX_WORD_SIZE, "%s%s" "%s%s" "%s",
        negative,
        sep(negative),
        word1,
        sep(word1),
        word2
        );
    return word;
}

int flush() {
    for(;;) {
        int ch = getchar();
        if(ch == EOF || ch == '\n')
            return ch;
    }
}

int main(void) {
    char word[MAX_WORD_SIZE];
    for(;;) {
        printf("Enter a two-digit number: ");
        int num;
        int rv = scanf("%d", &num);
        if(rv == EOF || flush() == EOF)
            break;
        if(rv != 1 || num < -99 || num > 99) {
            fprintf(stderr, "invalid input\n");
            continue; // or break?
        }
        printf("%s\n", get_number_word(num, word));
    }
    printf("\n");
}

示例会话(注意输入2a;如果你想更严格,那么你需要检查下一个输入是\n,例如“%d%c”;但是“%d”无论如何都会跳过前导空格,所以如果你想要严格的输入验证,请使用fgets()读取一行,使用strtol()读取一个数字):

Enter a two-digit number: hello world
invalid input
Enter a two-digit number: 2a
two
Enter a two-digit number: -1000000
invalid input
Enter a two-digit number: -100
invalid input
Enter a two-digit number: -99
negative ninety nine 
Enter a two-digit number: -1
negative one 
Enter a two-digit number: 0
zero 
Enter a two-digit number: 1
one
Enter a two-digit number: 19
nineteen
Enter a two-digit number: 20
twenty 
Enter a two-digit number: 21
twenty one 
Enter a two-digit number: 99
ninety nine 
Enter a two-digit number: 100
invalid input
Enter a two-digit number: ^D

相关问题