c - 我们如何保证 `fprintf(f, "%i", i)` 永远不会导致编码错误?

标签 c encoding printf runtime-error language-lawyer

我认为我们可以保证对 foo 的调用,

int foo (FILE * f, int i)
{
    return fprintf(f, "%i", i);
}

如果我们可以保证 i 不是陷阱表示(N2176,类型表示:常规),则永远不会产生编码错误,因为字符 '-' , '0', '1', '2', '3', '4 ''5''6''7''8'、和 '9' 可以在基本执行字符集(N2176,环境注意事项:字符集)中找到,并且这些都是表示可以表示为的任何整数值的十进制形式所需的全部内容一个int。此外,int 的十进制表示所需的字符数保证小于 INT_MAX(因此 fprintf 的返回值可以始终存储转换产生的字符数)。

所以,问题简化为:

我们如何保证 int 不存储陷阱表示?

(或者更复杂?)

更复杂。

添加此部分是为了回应迄今为止(2022 年 2 月 18 日)的答案和评论(关于方向)。

我认为我们可以保证对 fputi 和/或 fwputi 的调用,

#include <stdio.h>
#include <wchar.h>

int fputi ( int i , FILE * f )
{
    return fwide ( f , 0 ) <= 0
        ?  fprintf ( f ,  "%i" , i )
        : fwprintf ( f , L"%i" , i ) ;
}

// The only differences between fputi and fwputi should be:
// - their names and
// - the "<" or "<=" signs.

int fwputi ( int i , FILE * f )
{
    return fwide ( f , 0 ) < 0
        ?  fprintf ( f ,  "%i" , i )
        : fwprintf ( f , L"%i" , i ) ;
}

如果我们可以保证 i 不是陷阱表示(N2176,类型表示:常规),则永远不会产生编码错误,因为字符 '-' , '0', '1', '2', '3', '4 ''5''6''7''8'、和 '9' 可以在基本执行字符集(N2176,环境注意事项:字符集)中找到,并且这些都是表示可以表示为的任何整数值的十进制形式所需的全部内容一个int。此外,int 的十进制表示所需的字符数保证小于 INT_MAX(因此 fprintffwprintf 始终可以存储转换产生的字符数。

所以,问题简化为:

我们如何保证i不存储陷阱表示?或者,我们如何修改 fputifwputi 以便它们的行为可移植(即,对于遵守标准的所有实现保持一致)?也许在 return 语句之前插入:

// C-LIKE PSEUDO CODE
if ( isTrapRepresentation ( i ) ) exit ( EXIT_FAILURE ) ;

最佳答案

I think that we can guarantee that the call to foo,... will never produce an an encoding error if we can guarantee that i is not a trap representation

反例:

#include <stdio.h>
#include <wchar.h>
int main() {
  int i = fwprintf(stdout, L"Hello world!\n");
  i = fwprintf(stdout, L"Step A %d\n", i);
  i = fwprintf(stdout, L"Step B %d\n", i);
  i = fprintf(stdout, "Step C %d\n", i);  // Returns -1
  fwprintf(stdout, L"Step D %d\n", i);
}

输出

Hello world!
Step A 13
Step B 10
Step D -1

一旦流设置了方向(打印为宽字符或窄字符),即使没有陷阱值,不小心尝试以其他方式打印也会导致编码错误i中。


How can we guarantee that fprintf(f, "%i", i) will never result in an encoding error?

至少不要改变方向。

关于c - 我们如何保证 `fprintf(f, "%i", i)` 永远不会导致编码错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71150512/

相关文章:

c++ - 执行程序时调用任何 cURL 函数都会导致 "entry point not found"

java - Java中的编码问题

ios - url编码错误

将负数从 String 转换为 unsigned Long

java - 在 Java 中打印大型列出数组

c - fprintf(textFilepointer) 在文件中打印两次

c++ - 该递归函数如何工作?

c - "Illegal hardware instruction"来自非常简单的代码

c++ - 是否可以将 C++ 实现为带有宏的 C 库?

ruby - 如何在 Ruby 中解码 RFC 2047 编码的电子邮件 header ?