【问题标题】:How to avoid sprintf call in C如何避免在 C 中调用 sprintf
【发布时间】:2014-07-02 08:55:37
【问题描述】:

我必须准备一个必须通过套接字发送的字符串,该字符串是使用不同的数据类型 int、char、unsigned char 等构造的......因为我在很多地方都使用过它,所以我的 callgrind 报告说大部分sprintf 和 strcat 消耗的 CPU。

有人可以告诉我这个 sprintf 和 strcat 想法的替代方案吗?

下面是一段代码

    pData_temp = (char *)malloc(200);
    pData = (char *)malloc(500);
    sprintf(pData_temp, "String to be sent over socket at time %u $%04x",seconds,id);
    strncpy(pData,pData_temp,strlen(pData_temp);

    for in t(i=0; i < 1000; i++)
    {
        sprintf(pData_temp,"%02x%04x%08x%08x%08x",var1,var2,var3,var4,var5);
        strcat(pData,pData_temp);
    }
    sprintf(pData_temp,"\n");
    strcat(pData,pData_temp)

    sock_send(pData,strlen(pData);

    free(pData);
    free(pData_temp);

任何帮助appriciated。

问候

【问题讨论】:

  • 首先,停止转换malloc()的返回值。为了安全起见,使用snprintf() 而不是sprintf()
  • @user3477950 这两个sprintf 语句都是安全的。
  • 它可能需要很长时间,因为您至少要在循环中运行它一千次。
  • 不连接单个字符串并发送结果,而是直接发送单个字符串。
  • @user3631987 网络搜索将产生有关 malloc 的信息

标签: c


【解决方案1】:

您正在使用 Shlemiel the painter's algorithm

相反,您可以将pData 前进您写入的长度,而不是一遍又一遍地strcating。 sprintf 返回您需要添加的号码。

但正如@alk 在 cmets 中指出的那样,将pData_temp 直接写入套接字可能会更好 - 根本不用费心制作一个大字符串。

【讨论】:

  • 是的,我按照您的建议进行了操作,避免了分词,这有帮助,而且我无法在来自 pData_temp 的信息之间发送信息,而是需要创建一串信息并通过套接字转发。但我正在研究如何避免 sprintf,因为这似乎是更昂贵的操作......谢谢
  • 如果您只是将整数转换为十六进制字符串,您可以使用没有格式字符串解析开销的专用打印函数。简单示例:stackoverflow.com/q/4085612/10396
  • 是的,这就是我正在查看的内容,谢谢,我将为 %02x、%04x、%08x、%016x 等编写自己的函数。
【解决方案2】:

代码中有缓冲区溢出。您只需为 pData 分配 500 个字节,然后将 1000 个 30 字节字符串连接到它。

数据真的需要是 ASCII 码吗?您可以通过使用二进制数据而不是 ASCII 来提高算法的效率:-

struct Data // turn off padding!
{
   char var1;
   short var2;
   int var3, var4, var5;
};

void somefunc ()
{
   int i;
   for (i = 0 ; i < 1000 ; ++i)
   {
     struct Data data; 
     // set up the members of data
     socket_write (&data, sizeof data); // not a real function, pseudo-code!
   }
}

【讨论】:

  • 经验教训:不要在代码中使用“幻数”。而是将它们定义为常量。
  • 嗨,Skizz,我同意存在缓冲区溢出,这是我写的一个示例虚拟代码,用于解释我在寻找什么,在实际代码中,这已经被小心了。
  • 嗨 Ludin,我同意你的观点,我总是使用正确名称而不是幻数的 #define,编写这段代码只是为了解释我在寻找什么,无论如何感谢您的评论
猜你喜欢
  • 2020-09-24
  • 2019-09-02
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多