搜索
bottom↓
回复: 19

請 教"不確定參數個數的字串連接"StrAdd 的函數要怎麼寫最有效率?

[复制链接]

出30入8汤圆

发表于 2020-8-13 19:25:32 | 显示全部楼层 |阅读模式
請教各位神仙大哥,如果傳入的參數不確定個數,例如:

printf("str=%s\r\n",StrAdd("This ","is ","an ","apple ",""));

str=This is an apple


printf("str=%s\r\n",StrAdd("This ","is ","not ","an ","apple ",""));

str=This is not an apple


這個 StrAdd 的函數要怎麼寫最有效率?

( 小弟已經乖乖先搜尋過網路上的幾個 va_start 和 va_end 範例,但幾乎都是誤人子弟,鬼扯沒一個能編譯過關能用的 !)


感謝。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入984汤圆

发表于 2020-8-13 20:54:54 | 显示全部楼层
开发环境是什么
va_start 我记得gcc、IAR是没问题的

出10入0汤圆

发表于 2020-8-13 20:57:28 | 显示全部楼层
本帖最后由 yoz 于 2020-8-13 21:16 编辑

不建议自己写,试试用 sprintf。
参考:
https://stackoverflow.com/questi ... ize-of-varargs-in-c

There is no built-in way to get the number of vararg arguments passed in C.

You need to do one of the following:

pass in a count explicitly,
pass in a count implicitly (as printf() does via the number of conversion specifiers)
or use a sentinel value (such as NULL or 0) to indicate the end of the vararg list

出30入8汤圆

 楼主| 发表于 2020-8-13 21:31:21 | 显示全部楼层
Himem 发表于 2020-8-13 20:54
开发环境是什么
va_start 我记得gcc、IAR是没问题的

稟告大神,環境是 C,STM32 要用的。

出30入8汤圆

 楼主| 发表于 2020-8-13 21:51:23 | 显示全部楼层
試試改了一下:

char* StrAdd(char* msg, ... )
{
    va_list argp;
    int argno = 0;
    char* para;
    char rs_str[64];
    va_start(argp, msg);
    while (1)
    {
        para = va_arg(argp, char *);
        if (strcmp(para, "") == 0)
            break;
        printf("Parameter #%dis: %s\n", argno, para);
        argno++;
        strcat(rs_str, para);
    }
    va_end(argp);
    return rs_str;
}

printf("STR=%s\r\n",StrAdd("This ","is ","an ","apple " ,"")) ;


輸出:
Parameter #0is: is
Parameter #1is: an
Parameter #2is: apple
STR=is an apple

怪怪,第一個參數會被吃掉不見 ...........

出10入0汤圆

发表于 2020-8-13 22:58:16 | 显示全部楼层
本帖最后由 yoz 于 2020-8-13 23:03 编辑
puby 发表于 2020-8-13 21:51
試試改了一下:

char* StrAdd(char* msg, ... )


va_start

Initializes ap to retrieve the additional arguments after parameter paramN.

It is not possible to use va_arg without fixed parameters. You should AT LEAST have 1 non var_arg argument.

出30入8汤圆

 楼主| 发表于 2020-8-13 23:14:25 | 显示全部楼层
yoz 发表于 2020-8-13 22:58
va_start

Initializes ap to retrieve the additional arguments after parameter paramN.

敬愛的神仙大哥

小弟就是豬就是笨就是嫩才來求教的,別再用洋文折騰小弟了嘛。


剛看了一篇其他人寫的:
https://www.cnblogs.com/fnlingnzb-learner/p/6401841.html

小弟寫的順序好像也沒甚麼瑕疵 .....
您就乾脆御手幫小的改一下也行嘛。

出10入0汤圆

发表于 2020-8-14 16:18:07 | 显示全部楼层
puby 发表于 2020-8-13 23:14
敬愛的神仙大哥

小弟就是豬就是笨就是嫩才來求教的,別再用洋文折騰小弟了嘛。


使用 va_arg 的话,这个函数至少得有一个固定位置的参数

  1. void func(a, ...)
  2. {
  3.     va_list list;
  4.     va_start(list,a);
复制代码


va_start 是从参数 a 以后的参数开始算的。

对应你的代码,是从 msg 以后才开始算变长参数。
StrAdd("This ","is ","an ","apple " ,""),这里面的 "This" 对应的是 msg,所以没被算进去。

出30入8汤圆

 楼主| 发表于 2020-8-14 16:39:52 | 显示全部楼层
yoz 发表于 2020-8-14 16:18
使用 va_arg 的话,这个函数至少得有一个固定位置的参数

拜謝神仙大哥詳盡且耐心的回覆。

小弟揮淚感恩!

出10入0汤圆

发表于 2020-8-14 17:52:59 | 显示全部楼层
puby 发表于 2020-8-14 16:39
拜謝神仙大哥詳盡且耐心的回覆。

小弟揮淚感恩!


不必这么客气兄弟,咱们都是普通的技术人员,互相交流帮助。

出30入8汤圆

 楼主| 发表于 2020-8-14 21:42:48 | 显示全部楼层
抱歉抱歉,我又來了 ....
剛解決一個問題,結果又來一個!

同樣這個函式:

char* StrAdd(char* msg, ... )
{
    va_list argp;
    int argno = 0;
    char* para;
    char rs_str[64];
    va_start(argp, msg);
    while (1)
    {
        para = va_arg(argp, char *);
        if (strcmp(para, "") == 0)
            break;      
        argno++;
        strcat(rs_str, para);
    }
    va_end(argp);
    return rs_str;
}


printf("\r\n") ;     
printf("STR=%s\r\n",StrAdd("TEST ", "This ", "is ", "a ", "demo! ", "")) ;

printf("\r\n") ;
printf("STR=%s\r\n",StrAdd("TEST ",This ","is ","an ","apple " ,"")) ;


輸出結果:

STR=This is a demo!

STR=This is a demo! This?          <----( 應該是蘋果呀!)

第二次呼叫就失效了,媽呀、痛哭呀,請教為什麼 ?


出0入0汤圆

发表于 2020-8-14 22:06:12 | 显示全部楼层
xilinx ISE 软件安装目录内有个xil_printf.c可以直接使用。

出30入8汤圆

 楼主| 发表于 2020-8-14 22:32:19 | 显示全部楼层
wang110 发表于 2020-8-14 22:06
xilinx ISE 软件安装目录内有个xil_printf.c可以直接使用。

感謝神仙大哥!

才加了這三個引用,編譯上就出了錯,不敢亂改,請教小弟該在哪調整?

#include <ctype.h>
#include <string.h>
#include <stdarg.h>




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2020-8-14 22:39:11 来自手机 | 显示全部楼层
puby 发表于 2020-8-13 23:14
敬愛的神仙大哥

小弟就是豬就是笨就是嫩才來求教的,別再用洋文折騰小弟了嘛。

繁体的英文也不好?

出30入8汤圆

 楼主| 发表于 2020-8-14 23:19:02 | 显示全部楼层
huangqi412 发表于 2020-8-14 22:39
繁体的英文也不好?

您甚麼意思?請明說。

同是中國人,這兒是搞技術的,建議您別挑撥敏感的議題 !

出0入0汤圆

发表于 2020-8-14 23:31:26 | 显示全部楼层
prinf() 和 sprintf() 是根据第一个 format 参数中 %s, %d 这类占位符来得知后边可变参数的个数和类型的
所以从原理上来说,如果你 StrAdd() 要拼接的都是字面量字符串,那就直接写成 "aaa " "bbb " 这样就好了,不要 StrAdd() 了
如果有字符串不是字面量字符串,那就需要在 StrAdd() 的参数中加一个字符串数量,然后里边用 va_arg 这一套东西逐个拿到指针后,再用 strcat() 拼接。当然肯定还得先分配好空间了,用完了还别忘了释放。

出0入0汤圆

发表于 2020-8-15 00:06:07 | 显示全部楼层
puby 发表于 2020-8-14 21:42
抱歉抱歉,我又來了 ....
剛解決一個問題,結果又來一個!

另外这段代码中你的函数返回了局部变量 rs_str, 这个数组的空间是在栈中分配的,任何时候这样用都是错误的

出30入8汤圆

 楼主| 发表于 2020-8-15 10:33:09 | 显示全部楼层
wudicgi 发表于 2020-8-15 00:06
另外这段代码中你的函数返回了局部变量 rs_str, 这个数组的空间是在栈中分配的,任何时候这样用都是错误 ...

深深拜謝神仙大哥耐心指引,好生感動。

但小弟底子薄,如同小學生聽不懂微積分的道理,可否恭請神仙大哥幫小弟直接改了這段代碼,小弟好做為範例研究,澳理俾以永銘在心,感恩感恩。

char* StrAdd(char* msg, ... )
{
    va_list argp;
    int argno = 0;
    char* para;
    char rs_str[64];
    va_start(argp, msg);
    while (1)
    {
        para = va_arg(argp, char *);
        if (strcmp(para, "") == 0)
            break;      
        argno++;
        strcat(rs_str, para);
    }
    va_end(argp);
    return rs_str;
}

出0入0汤圆

发表于 2020-8-16 17:05:04 | 显示全部楼层
puby 发表于 2020-8-14 23:19
您甚麼意思?請明說。

同是中國人,這兒是搞技術的,建議您別挑撥敏感的議題 ! ...

这都哪跟哪

出16170入6148汤圆

发表于 2020-8-23 12:10:34 来自手机 | 显示全部楼层
 【請 教"不確定參數個數的字串連接" 】标题不合格。标题不合格,这次我帮你修改了。你是VIP++不用警告。

    标题必须充分说明帖子内容
     比如你要问AVR的ADC如何才能测量得比较准确,使用标题:“AVR的ADC如何消除干扰测量得比较准确?”。以下的标题不合格:
           不合格举例1:小女子冰天雪地裸体跪求解决方法
          不合格举例2:高手请出招,一个无法解决的AVR问题
          不合格举例3:一个困扰学习单片机初学者,惊动单片机开发者的难题 
          不合格举例4:AVR的ADC测量   (点评:问问题,或是有技术心得与大家分享?)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 16:44

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表