【问题标题】:sprintf and allocating memorysprintf 和分配内存
【发布时间】:2013-11-27 08:00:03
【问题描述】:

我有一个结构,其中存储了一些值,如下所示:

struct cmd { 
    char *pname;
    char *pdesc;
}; 

在初始化之后我做了:

struct cmd[] = {{"show", "show items"},
                {"exit", "exit the shell"},
                {"setitem",   "setting item"}
               };    

我正在使用sprinf() 通过存储所有 pname 和 pdesc 来打印,如下所示,

int length = 0;    
char *resultcmd;    
for (indx = 0; indx< cmdCount; indx++) {
     length += sprintf(resultcmd+length, cmd[indx].pname, cmd[indx].pdesc);    
}    

请帮助我如何为 resultcmd 分配内存,当我将 resulecmd 设置为一定长度的数组时,它起作用了,但是如果添加更多 pname 和 pdesc 缓冲区溢出。请帮帮我。

【问题讨论】:

  • 使用 strlen 计算字符串长度。
  • 你能提前算出所需的总内存吗?
  • 如果使用glibc 并且不关心对其他libc 实现的可移植性,会说坚持使用gcc,您可能想看看asprinf()

标签: c malloc printf dynamic-memory-allocation


【解决方案1】:

如果您想安全地将数据输出到缓冲区resultcmd,您必须先找出它的长度并使用它:

size_t length = 1; // 1 symbol needed to store \0', 
                   // because strlen() returns length 
                   // without NULL-termination symbol
// compute length:
for (intx = 0; indx < cmdCount; indx++) {
     length += strlen(cmd[indx].pname) + strlen(cmd[indx].pdesc);
}

char *resultcmd = malloc(length);
int written = 0, ret = 0;

// print cmds to C string
for (indx = 0; indx < cmdCount; indx++) {
     ret = snprintf (resultcmd + written, length - written, 
                     "%s%s", cmd[indx].pname, cmd[indx].pdesc))
     if (0 > ret) {
         fprintf (stderr, "snprintf() error: %s\n", strerror(errno));
         break;
     } else {
         written += ret;
     }
}
/* 
 * some useful code here
 */
free(resultcmd);

【讨论】:

  • 你不需要 sprintf 的格式参数吗? sprintf(resultcmd+length, cmd[indx].pname, cmd[indx].pdesc);应该是 sprintf(resultcmd+length, "%s%s", cmd[indx].pname, cmd[indx].pdesc);实际上,它应该是一种看起来不错的格式...
  • @thang 谢谢。固定的。而且,如果没有格式参数,pdesc 根本不会被打印出来。
  • @Michael 我认为您对length 的使用是错误的。从malloc() 开始,您应该重置它或使用第二个“光标”变量。
  • 我宁愿使用int crsr = 0; for (indx = 0; indx&lt; cmdCount; indx++) { crsr += snprintf(resultcmd+crsr, length-crsr, "%s%s", ...); } 以保留原来的length 并增加一点安全性。
  • @glglgl 再次感谢大家!将您的所有想法添加到答案中。现在应该没事了。
【解决方案2】:

您可以使用snprintf(char *dest, size_t maxlen, char *fmt, ...) 来限制打印的大小。如果函数失败,它会返回如果有足够的空间,将会写入的字符数;这样 +1 就是你需要的 realloc

【讨论】:

    猜你喜欢
    • 2011-04-16
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2018-07-12
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多