C# 应用程序中的 PrintF






2.88/5 (7投票s)
C/C++ 到 C# 的兼容性 DLL
引言
本文面向将 C/C++ 代码移植到 C# 的程序员。从 C/C++ 移植到 C# 的代码,当涉及到 printf 时可能会耗费大量精力,因为 printf 具有一些 C# 没有以相同方式提供的功能。因此,我编写了随附的 DLL,它允许在 .NET 框架中使用 printf。
要简要了解 printf,您可以访问以下页面
- https://msdn.microsoft.com/en-us/library/8aky45ct.aspx
- http://www.cplusplus.com/reference/cstdio/printf/
使用代码 - 标准方法
在大多数情况下,使用 PrintFCompatibility
类的静态方法就足够了。它提供以下静态方法/属性
FPrintF
(用于打印到文件流)PrintF
(用于打印到标准输出;另请参阅 PrintfPrint 属性)SnPrintF
(用于打印到字符串,并定义最大字符数)SPrintF
(用于打印到字符串)PrintfPrint
(用于为 PrintF 函数分配输出。默认值为控制台输出,但您可以将其更改为任何其他受支持的输出,例如任何类型的流或变量)。
以下代码取自 Test 程序,展示了基本功能。
int length;
// Use Standard output: Console
length = CppCompatibility.PrintFormatted.PrintFCompatibility.PrintF("%f\n", 3.14159265d);
/*
length = 9
Console output:
3.1415923 and line feed.
*/
// Change standard output to stream
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
CppCompatibility.PrintFormatted.PrintFCompatibility.PrintfPrint =
new CppCompatibility.PrintFormatted.PrintFStream(memoryStream,
System.Text.Encoding.Unicode);
length = CppCompatibility.PrintFormatted.PrintFCompatibility.PrintF("%f", 3.14159265d);
memoryStream.Close();
memoryStream.Dispose();
/*
length = 8
Stream content:
3.1415923
*/
// Printing into a string
string formatted;
length = CppCompatibility.PrintFormatted.PrintFCompatibility.SPrintF(out formatted, "%f", 3.14159265d);
/*
length = 8
String value: 3.1415923
*/
使用代码 - 流
如果您想打印到多个流,使用 PrintFCompatibility
类可能会很麻烦。相反,您可能希望使用以下类
PrintFFileStream
PrintFStream
上述每个类的实例都可以处理自己的流,从而简化您的代码。
以下代码取自 Test 程序,展示了 IPrintf 接口以及 PrintFStream 和 PrintFFileStream 类的用法
// Using PrintF classes directly: (here PrintFConsole class)
CppCompatibility.PrintFormatted.IPrintF printfConsole =
new CppCompatibility.PrintFormatted.PrintFConsole(true);
length = printfConsole.PrintF("Error Console: %20.15f\n", 3.14159265d);
/*
length = 36
Console output:
Error Console: 3.141592650000000 and line feed.
*/
// Using a file stream directly with the PrintFFileStream class
string tempFilePath = System.IO.Path.GetTempFileName();
System.IO.FileStream fileStream = new System.IO.FileStream(tempFilePath, System.IO.FileMode.OpenOrCreate);
CppCompatibility.PrintFormatted.IPrintF printfFile =
new CppCompatibility.PrintFormatted.PrintFFileStream(fileStream,
System.Text.Encoding.UTF8);
length = printfFile.PrintF("File Stream: %20.15f\n", 3.14159265d);
fileStream.Close();
fileStream.Dispose();
/*
length = 34
File content:
File Stream: 3.141592650000000 and line feed.
*/
创建 PrintFFileStream
或 PrintFStream
对象后,只需在该对象上使用 PrintF
函数即可。
如果您不想使用上述方法,可以使用以下方法与 PrintFCompatibility
类配合使用
- 指定 PrintfPrint 对象并按照“使用代码 - 标准方法”部分所示使用 PrintF
- 对于文件流,始终使用
FileStream
对象指定PrintFCompatibility
类的 FPrintF 方法。
使用代码 - 控制台
如果您想使用控制台输出,可以使用 PrintFConsole
类。它的构造函数允许您指定是否要使用错误控制台(将 useErrorConsole
参数指定为 true),或者使用标准控制台(不指定 useErrorConsole
参数或将其设置为 false)。
// Error console output
bool useErrorConsole = true;
CppCompatibility.PrintFormatted.IPrintF printfFile =
new CppCompatibility.PrintFormatted.PrintFConsole(useErrorConsole);
printfFile.PrintF("%20.15f\n", 3.14159265d);
// Standard console output
useErrorConsole = false;
CppCompatibility.PrintFormatted.IPrintF printfFile =
new CppCompatibility.PrintFormatted.PrintFConsole(useErrorConsole);
printfFile.PrintF("%20.15f\n", 3.14159265d);
// Standard console output
CppCompatibility.PrintFormatted.IPrintF printfFile =
new CppCompatibility.PrintFormatted.PrintFConsole();
printfFile.PrintF("%20.15f\n", 3.14159265d);
“n” 格式
C/C++ 定义了“n”格式,它打印到指定“n”格式的点为止输出的字符数。它期望输出到已签名整数变量的地址。这导致了以下困境
- 在 C# 函数中更新 int 变量需要使用 ref 关键字指定该变量。
- 为了与 C/C++ 兼容,接口为所有函数调用指定了 params 关键字。但是,这使得无法使用 ref 关键字指定变量。
解决方案是使用 FormatInfoN
类
FormatInfoN fin = new FormatInfoN();
string result;
int length = PrintFCompatibility.SPrintF(out result, "%15d%n", 13, fin);
int characterCount = fin.PrintedCharacterCount;
历史
版本号 | 描述 |
---|---|
0.1 | 首次发布 |
0.2 | 固定处理格式说明符中的纯文本。 |