当我尝试打印从C的va_list获取的字符串时,我遇到了解码错误

时间:2014-03-26 00:18:25

标签: c variadic-functions

运行良好,但如果删除main() "printf("(main)s: %s\n",s);

中的第三行

输出遇到解码错误:它打印unrecognized chars而不是helo world

这是我的代码:

#include <stdio.h>
#include <stdarg.h>
void fun1(int i, ...){
    va_list arg_ptr; 
    char *s=NULL; 

    va_start(arg_ptr, i); 
    s=va_arg(arg_ptr, char*); 
    va_end(arg_ptr); 
    printf("address of s in fun1: %x\n",&(*s));
    printf("(fun1)s: %s\n",s); 
    return; 
}
void main(){
    char *s = "hello world";
    printf("        address of s: %x\n",&s);
    printf("(main)s: %s\n",s);
    fun1(4);
}

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

因为printf函数说的是%x而不是%s %x代表unsigned hexadecimal integer%s代表一串字符

warning: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'char**'

要打印char array的地址,可以尝试将数组的值复制到int变量。

您的问题是

printf("        address of s: %x\n",&s); ///< this line right here

变量schar*&schar**,使用%x您隐含地将char**强制转换为int {1}}并将打印在hex中。

  

(ISO / IEC ISO / IEC 9899:1999(E),§6.3.1.1) [...]如果int可以表示原始类型的所有值,则转换该值到一个int;否则,它将转换为unsigned int。这些被称为整数促销。

当您删除该行时,我听说您出现问题:printf("(main)s: %s\n",s);

因此,如果您的char**被隐式转换为intuint,然后会在hex中显示,并且知道您正在查看哪个地址。

You can check everything about how to format printf here

答案 1 :(得分:1)

好像你爱UB。

  1. %x不适用于打印指针。使用%p(但仅限于打印void*char*)。
  2. 您正在使用第一个var_arg_parameter,但是您没有通过它。
  3. 除非您处于独立环境(微控制器等),否则您的主机原型不佳。使用int main()int main(int argc, char** argv)
  4. 此外,您可能希望打印s resp。你通过的参数,而不是它存储的地方。

    补充说明:UB表示Undefined Behavior,这是任何C / C ++程序员应该知道的首字母缩略词。它的字面意思是,&#34;这个程序可以表现出任何行为,包括让恶魔飞出你的鼻子。&#34;在任何特定情况下实际发生的事情都可能是完全不可预测的,并且随着时间的推移而改变。

    #include <stdio.h>
    #include <stdarg.h>
    void fun1(int i, ...){
        va_list arg_ptr; 
        char *s; /* removed superfluous initialisation */
    
        va_start(arg_ptr, i); 
        s=va_arg(arg_ptr, char*); 
        va_end(arg_ptr); 
        printf("address of s in fun1: %p\n",(void*)&s);
        printf("value of s in fun1: %p\n",s);
        printf("address of string s: %p\n",s);
        printf("value of string s: %s\n",s); 
        return; 
    }
    int main(){
        char *s = "hello world";
        printf("address of s in main: %p\n",(void*)&s);
        printf("value of s in main: %p\n",s);
        printf("address of string s: %p\n",s);
        printf("value of string s: %s\n",s); 
        fun1(4, s); /* fun1 will always access the first var-arg parameter as a string, so you must provide it */
        return 0; /* can be omitted but only for main, so why do it? */
    }