vsnprintf和gcc

时间:2010-07-29 13:33:32

标签: c++ c gcc printf

我有以下声明:

vsnprintf(target, size - 1, "%ls_%ls", str16_1, str16_2);

为什么这会在gcc上失败?

我在Windows上使用过这样的:

vsnprintf(target, size - 1, "%S_%S", str16_1, str16_2);

它按预期工作。在gcc文档中我发现%S是%ls的同义词,但我不能使用它。我也试过%S,但是没有用。我在具有可变参数列表的函数中使用它。是否可能无法工作,因为我更改了传递给va_start的格式变量?我必须搜索%S并将其替换为格式变量中的%ls。

该功能类似于:

void f(const char* format, ...){
  char* new_format = format with %S replaced with %ls;
  va_list argptr;
  va_start(args, format);
  vsnprintf(str, size-1, new_format, argptr);
}

我检查过,new_format是正确的。

谢谢!

6 个答案:

答案 0 :(得分:8)

尝试使用snprintf,原因是vsnprintfvsnprintf采用类型为va_list的参数,而不是文字可变参数列表。例如:

va_list ap;
va_start (ap, first_arg_in_this_function);
vsnprintf (buf, size, format_str, ap);
va_end (ap);

而使用sprintf:

snprintf (buf, size, format_str, x, y);

在......

时使用v*printf
  1. 围绕printf样式函数制作包装器
  2. Variadic宏不是一个选项
  3. 否则只需使用*printf

答案 1 :(得分:2)

您对va_start的使用不正确。在这个声明中:

va_start(args, new_format);

您没有引用format函数的f()参数。 va_start() 的第二个参数必须引用函数形式参数列表中的参数。其他任何事情都可能是未定义的行为。

编译器使用va_start()中的命名形式参数来确定在函数调用中从哪里开始查找变量参数列表。它不会自动知道你在参数列表中放置...的位置(也许你可能会认为它应该存在,但这不是它的工作方式)。

答案 2 :(得分:2)

我向%ls查找了vsnprintf,发现这是用于打印/格式化宽字符串的格式说明符,即wide_t *p = L"Hello world!";

在C ++中花了一些时间和谷歌搜索广泛的字符用法(我喜欢下面的页面:http://www.linux.com/archive/feed/51836),但我想我找出了你的问题。

如果您将char字符串传递给%ls,那么它就不会展开,但如果您将wchar_t字符串传递给%ls ,那么< / strong>它打印。

根据您的信息考虑以下示例代码:

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


char       str[100];


void f (const char    *format,
        ...)
{
    va_list    args;

    va_start(args, format);
    vsnprintf(str, sizeof(str), format, args);
    va_end(args);
}




int
main ()
{
    char    *p1 = "1234";
    char    *p2 = "abcd";

    wchar_t    *pw1 = L"9876";
    wchar_t    *pw2 = L"wxyz";



    f("%d_%d", 120, 199);
    printf("numbers: %s\n", str);


    f("%s_%s", p1, p2);
    printf("char*: %s\n", str);


    f("%ls_%ls", p1, p2);
    printf("wide char* with char* input: %s\n", str);


    f("%ls_%ls", pw1, pw2);
    printf("wide char* with wide char* input: %s\n", str);


    return (0);
}

我用g ++编译了这个。

make newtest.exe
g++ -g -c -MD -Wall -Werror  newtest.cxx
g++ -o newtest.exe newtest.o -lc -lrt

Compilation finished at Thu Jul 29 08:54:57

输出如下:

[SUSE10.1]:201> newtest.exe
numbers: 120_199
char*: 1234_abcd
wide char* with char* input: 
wide char* with wide char* input: 9876_wxyz

答案 3 :(得分:0)

使用snprintf

答案 4 :(得分:0)

您的valist类型是什么?变量列表参数的正确类型是带有下划线的va_list,没有?

答案 5 :(得分:0)

因为我在Mac上使用它,我找到了解决办法:

How to "pass on" a variable number of arguments to NSString's +stringWithFormat:

似乎vsnprintf无法处理16位字符串。也许是因为wchar_t不是16位。