将C++的sprintf格式字符串翻译成C#的string.Format

5
我发现了以下的C++代码(注释是我自己加的):
// frame_name is a char array
// prefix is std::string
// k is a for loop counter
// frames is a std::vector string
sprintf(frameName, "%s_%0*s.bmp", prefix.c_str(), k, frames[k].c_str());

我接着尝试将它翻译成C#。

// prefix is string
// k is a for loop counter
// frames is List<string>
string frameName = string.Format("{0}_(what goes in here?).bmp", prefix, k, frames[k]);

基本上,C#中与C++格式字符串“%s%0 * s.bmp”等效的是什么?

编辑,@Mark Byers:

我尝试了您的代码并制作了一个小测试程序:

static void Main(string[] args)
{
    List<string> frames = new List<string>();
    frames.Add("blah");
    frames.Add("cool");
    frames.Add("fsdt");

    string prefix = "prefix";
    int n = 2;
    int k = 0;
    string frameName = string.Format("{0}_{1}.bmp", prefix, frames[k].PadLeft(n, '0'));
    Console.WriteLine(frameName); // outputs prefix_blah.bmp, should output prefix_00blah.bmp
    Console.ReadLine();
 }

由于某些原因,它没有填充。

编辑:已解决;如果n = 2,则不会填充。


你确定要将 k 用于两个不同的目的吗? - Mark Byers
你确定这些格式字符串没问题吗?特别是:%0*s - 根据这里的手册页面,与s转换结合使用的0修饰符是未定义行为。 - Thanatos
这是我在查看一个开源程序时得到的。 - thebackup
你不应该假设你所得到的是正确的。请检查文档。 - Mark Byers
2个回答

3

要在字符串前面填充零,请使用string.PadLeft方法:

frames[k].PadLeft(n, '0')

string.Format 结合使用:
int n = 15; // Get this from somewhere.
string frameName = string.Format("{0}_{1}.bmp",
                                 prefix,
                                 frames[k].PadLeft(n, '0'));

请注意,我已将k更改为n,因为我认为这是原始代码中的错误。我认为文件名填充的长度不太可能在循环的每次迭代中增加一个字符。

谢谢,但显然不是填充;请参阅原帖。 - thebackup
@thebackup:这不是填充,因为你已经将n设置为2。n是最小长度。如果你只想始终添加两个零,那么这样做会更容易,而且不需要使用PadLeft函数。 - Mark Byers
哦,好的,我明白了;它按预期工作 - 这正是我想要的。非常感谢,马克。 - thebackup

1

对于像%0*s中的0*这样的格式细节,我会这样做:

string.Format("{0}_{1}.bmp", prefix, frames[k].PadLeft(k,'0'));

如果我理解正确,它将使用frames[k],并在左侧填充0。

e.g.:

k=10;
frames[k] = "Hello";
frames[k].PadLeft(k,'0') ==> "00000Hello";

这是你想要的吗?


1
%0*s 中的 * 表示请求使用参数来指定精度。因此,%s 为 1,* 为 1,%0*s 也为 1,总共为 3。 - Thanatos
除了 0s 之外,似乎会出现 UB - 请参见我在问题中的评论。 - Thanatos
谢谢,我要测试一下这段代码;我会告诉你结果的。 - thebackup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接