【问题标题】:Print actual value of int when passed to a function that accepts a char parameter当传递给接受 char 参数的函数时打印 int 的实际值
【发布时间】:2015-04-21 06:07:12
【问题描述】:

我有一个函数PutChar(int, int, char),它在给定的行和列打印出给定的字符。如果我传递一个字符,这个函数就可以正常工作。我还希望能够将 0-9 范围内的 int 传递给函数并让它打印实际的 int 值。例如,我想用下面的代码打印 int x 的实际值:

int x = 5;
PutChar(1, 1, x);

void PutChar(int row, int col, char ch) {
    char str[20];

    sprintf(str, "\e[%d;%dH", row, col); // move cursor to row-col
    write(1, str, strlen(str)); 
    write(1, &ch, 1);
}  

在将 int 传递给函数时,我尝试强制转换为 char,但它会打印出奇怪的字符。

编辑:可以打印的整数范围是 0-9。这是一个家庭作业,所以我无法更改函数的原型。

【问题讨论】:

  • 是修改PutChar还是直接输出1位整数?

标签: c char int


【解决方案1】:

如果您应该使用PutChar() 函数来输出单个数字,可以很容易地通过添加'0' 将它们转换为具有适当值的char,正如Shan 所建议的那样:

PutChar(1, 1, x + '0');

如果您应该修改PutChar() 函数以在传递小整数时输出数字,也可以这样做。

假设您的终端支持 ASCII 或某些基于 ASCII 的编码,例如 Latin1 或 UTF-8,32(空格)以下的字符是控制字符。将它们放置到屏幕上的给定位置是没有多大意义的。因此,您可以修改 PutChar() 以专门处理 09 之间的 char 值,而不会与实际 ASCII 字符 32 及以上的当前行为冲突(如果 char 已签名,则甚至为负):

void PutChar(int row, int col, char ch) {
    char str[20];

    sprintf(str, "\e[%d;%dH", row, col); // move cursor to row-col
    write(1, str, strlen(str));
    if (ch >= 0 && ch <= 9)
        ch += '0';  // convert small integer to digit
    write(1, &ch, 1);
}

void Test(void) {
    for (int x = 0; x < 10; x++) {
        PutChar(x + 1, x + 1, x);
    }
}

还请注意,您的程序是不安全的:sprintf 将导致 rowcol 的较大值的缓冲区溢出。您应该使用snprintf() 和更大的缓冲区。您可以进一步简化代码,只需调用一次write

void PutChar(int row, int col, char ch) {
    char str[46];
    int len;

    if (ch >= 0 && ch <= 9)
        ch += '0';  // convert small integer to digit
    len = snprintf(str, sizeof str, "\e[%d;%dH%c", row, col, ch);
    if (len > 0)
        write(1, str, len);
}  

【讨论】:

  • 好答案。为了获得额外的积分和更高的可靠性,还可以捕获控制字符 (c126 的字符并为它们打印符号表示,而不是让它们弄乱输出,或者更糟的是,终端。
  • @Peter Schneider:对于 0 到 31 之间的字符,可能还有 127 的字符很好。低于 0 或高于 127 的字符在 Latin1 终端上完全可以。
【解决方案2】:

您需要使用sprintf() 来实现此目的。在那里,您可以使用任一

  • %c 打印 char
  • %d 打印 int 值。

但是,您需要更改逻辑以包含一个 标志 来指示任何一种情况。

【讨论】:

  • 有没有其他方法可以通过对函数使用相同的原型来做到这一点。教授希望我们使用那个原型。可以传递给该函数的整数范围是 0-9。在函数调用中有什么我可以做的吗?
  • @Shan 是的,这可以做到,但是您将如何决定是要char 表示还是int 表示?顺便说一句,在不改变函数原型的情况下,对于单线程程序,您可以使用 global 标志变量来实现。
  • @Sourav Ghosh:您将 OP 发送到错误的轨道上。规范很明确:如果 char 参数在 0-9 范围内,则打印数字,否则打印字符。
  • @chqrlie 不,恕我直言,你所说的根本不是 OP 提到的,至少,我会说不清楚。
  • @chqrlie 即使从你的角度来看,value 本身也可以用作 flag,不是吗?
【解决方案3】:

对我来说,让PutChar() 函数打印除字符之外的其他内容似乎不是一个好主意。

如果您需要打印一个 int,请编写一个函数 PutInt() 来执行此操作。您可能需要另一个函数 PutString() 来实现。

完成后,您可能已经重写了标准库的大部分内容...

【讨论】:

  • 这是个坏主意,但这是任务。 OP 应该生成工作代码很容易......他是否想就问题的正确性与老师对质是另一回事。
  • 这是最初不可用的新信息。而且我简直不敢相信老师会提出一项根本不可能的任务。 charchar,如果不违反规则,就无法通过该参数传递 int
  • 当然有!这不是java 也不是C++。没有违反规则:传递给PutChar()int 被转换为char 类型。 PutChar() 语义可以更改为在09 范围内的ch 值的输出数字。无法区分 PutChar(row, col, 1);PutChar(row, col, '\001');,以及 Putchar(row, col, 'A');PutChar(row, col, 65);,但这真的重要吗?
  • charchar,而不是int。 TO 没有询问如何输出char 的数值,而是询问如何将int 通过 传递给char 函数参数。这显然是不可能的。
  • 我认为你错了,这是可能的,这里有一个例子:Putchar(row, col, 'A')。在C 中,char 是整数类型。 charint 类型之间的转换是自动且透明的。事实上,在 C 语言中,'A'类型为int 的常量。同样,"%c" 格式的printf 参数是int。当然,char 的签名可能会在非 ASCII 字符转换为int 时产生令人惊讶的结果,并且int 的大值不适合char 类型。这与C++ 不同,其中sizeof('A') == 1 .
【解决方案4】:

由于整数的范围是 0-9,我可以在传递的参数中添加“0”。例如:

int x = 5;
PutChar(1, 1, x + '0');

【讨论】:

    【解决方案5】:

    如果对您可行,您可以在 PutChar 实现中使用 VA_ARGS:

    PutChar(int row, int col, char* formatString, ...) {
        sprintf(str, "\e[%d;%dH", row, col); // move cursor to row-col
        va_list args;
        va_start (args, format);
        vprintf (format, args); // untested example
        va_end (args);
    }
    

    【讨论】:

    • @chqrlie 我在 OP 声明他无法更改函数原型之前发布了这个答案。当他发布 PutChar 的源代码时,我认为这是他自己的函数,他可以随意编辑。
    【解决方案6】:

    在调用PutChar()之前,如果要输出0..9范围内的int,则将0x30添加到字符中。如果要输出任何其他char,则不要添加 0x30

    【讨论】:

    • 你应该使用'0'而不是用0x30硬编码ASCII。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多