【问题标题】:C sprintf implementation with pointers带指针的 C sprintf 实现
【发布时间】:2020-09-09 10:54:42
【问题描述】:

我正在尝试编写一个代码,该代码采用一个缓冲区、一个格式字符串和三个指向值的 void 指针,并组成一个具有相同文本的字符串,如果在 printf 上使用格式,则该字符串将被打印。指向的值应替换格式字符串中的 3 个占位符。我开始只为%c 占位符的情况编写代码,并且缓冲区似乎包含随机字符而不是被指向的字符。任何帮助将不胜感激:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int format_to_string(char *buffer, char *format, void *arg1, void *arg2, void
*arg3);
int main(){
char format[20] = "%c bla %c bla %c";
int v1='5'; 
char v2 ='c';
char v3 = 'F';
void *arg1 = &v1;
void *arg2 = &v2;
void *arg3 = &v3;
char str[20];
char *buffer = str;
format_to_string(buffer,format, &arg1, &arg2,&arg3);
printf("%s",buffer);
return 0;

}
int format_to_string(char *buffer, char *format, void *arg1, void *arg2, void
*arg3)
{
    int counter = 0;
    for(int i=0; *format != '\0'; format++, buffer++ )
    {
        if( *format != '%')
        {
            *buffer = *format;
        }
        else
        {
            format++;
            if(*format == 'c')
            {
                if(counter == 0)
                {
                    *buffer =*(char*)arg1;
                    counter++;
                    continue;
                }
                if(counter == 1)
                {
                    *buffer =*(char*)arg2;
                    counter++;
                    continue;
                }
                if(counter == 2)
                {
                    *buffer =*(char*)arg3;
                    counter++;
                    continue;
                }
            }    
        }

    }   
    *buffer = '\0';
    return 0;
}

【问题讨论】:

  • 旁白:极端情况错误:请注意,如果格式是意外的“abc %”,代码将增加 format 超过 '\0';建议if(*format == 'c') { .... } else { *buffer = '\0'; return 0; }尽早退出解析,不要走得太远。

标签: c pointers format printf buffer


【解决方案1】:

对于format_to_string 的每个额外参数,您将它们作为指向 char 的指针(两级间接)的指针发送,而函数期望指向 char 的指针(一级间接)。您可以通过以下任一方式解决此问题:

1) 将调用中的参数类型更改为format_to_string,以便您只将指针传递给先前定义的字符。 (根据您当前的代码,这是最有意义的)。

    void *arg1 = &v1;
    void *arg2 = &v2;
    void *arg3 = &v3;
    //...
    format_to_string(buffer,format, arg1, arg2,arg3);

2) 更改format_to_string的参数类型

    int format_to_string(char *buffer, char *format, void **arg1, void **arg2, void **arg3)
    {
    //...
                if(counter == 0)
                {
                    *buffer =**(char*)arg1;
                    counter++;
                    continue;
                }
    //...
    }

附:如果您有兴趣接受三个以上的参数(如 printf),您可以使用 variable argument lists

【讨论】:

    【解决方案2】:

    你的间接性有点过分了。你有:

    format_to_string(buffer,format, &arg1, &arg2,&arg3);
    

    但是arg1arg2arg3 已经是指针。因此,您正在获取您的值的地址的地址,而您要打印的是值的地址而不是值本身。相反,只需传递参数:

    format_to_string(buffer,format, arg1, arg2, arg3);
    

    【讨论】:

      猜你喜欢
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      相关资源
      最近更新 更多