简体   繁体   English

c ++函数就像printf一样

[英]c++ function like printf

i have this function 我有这个功能

char* copy(char* pString,...){
    char *vToate;
    int vLen;
    va_list vAp;
    va_start(vAp,pString);
    vLen+=strlen(pString);
    va_end(vAp);

    vToate=new char[vLen+1];

    va_list vAp1;
    va_start(vAp1,pString);
    strncpy(vToate,pString,strlen(pString));
    va_end(vAp1);
    return vToate;
}

if i try this 如果我试试这个

char *vTest="test";
char *vTmp=copy(vTest," ",vTest);
cout<<vTmp;

the result are "test" not "test test" what are wrong ? 结果是“测试”而不是“测试”有什么错?

It seems like you expect va_start / va_end to do a sort of loop over the parameters. 看起来你希望va_start / va_end对参数进行一种循环。 That's not the case at all, you need to do the iteration yourself. 事实并非如此,您需要自己进行迭代。

But variadic functions don't provide a way of getting the number of arguments passed, so you can't loop safely the way you are doing it either. 但是可变参数函数无法提供获取传递的参数数量的方法,因此您也无法以安全的方式进行循环。 You'll need to: 你需要:

  • Change the first parameter so that it indicates the number of arguments you're passing. 更改第一个参数,使其指示您传递的参数数量。
  • Change the calling convention so you allways pass a NULL as the last argument. 更改调用约定,以便始终将NULL作为最后一个参数传递。

Both of there are error-prone and require careful coding at the call sites, which is not great. 两者都容易出错,并且需要在呼叫站点进行仔细编码,这并不是很好。

Look here for an example of how to iterate over the parameters. 在这里查看如何迭代参数的示例。

You should really consider using std::string s. 您应该真正考虑使用std::string They have a handy operator+ , so you don't have to do any of that trickery. 他们有一个方便的operator+ ,所以你不必做任何这样的诡计。

If you really do want to do it the hard way, make sure that: 如果你确实想要这么做,请确保:

  • You initialize your local vLen parameter 您初始化本地vLen参数
  • Use strcat to concatenate C-style strings (safe as long as you really did allocate enough memory, but not the most efficient here) 使用strcat连接C样式的字符串(只要您确实确实分配了足够的内存,就可以安全使用,但是这里并不是最有效的)

The critical line is this one: 关键是这一条:

strncpy(vToate,pString,strlen(pString));

You're copying the contents of the argument string to the beginning of your output string. 您正在将参数字符串的内容复制到输出字符串的开头。 You need to given strncpy() a pointer past the point of your last copy so that you're appending data rather than overwriting. 你需要给strncpy()一个指针超过你上一个副本的点,这样你就可以附加数据而不是覆盖。

char* vCpy = vToate;
int len = 0;
va_list vAp1;
    va_start(vAp1,pString);
        len = strlen( pString );
        strncpy( vCpy, pString, len );
        vCpy += len;
va_end(vAp1);

The above comments also apply. 以上评论也适用。

What you miss is some loop, extracting va_arg . 你错过了一些循环,提取va_arg Also, you give no hints as to how many arguments you're passing, you should either terminate the list with NULL or pass the number. 此外,您没有提供有关您传递的参数数量的提示,您应该使用NULL终止列表或传递数字。

What you have produced isn't really C++, but in terms of the output you are seeing I believe: 你所产生的并不是真正的C ++,但就你所看到的输出而言,我相信:

strncpy(vToate,pString,strlen(pString));

Is merely taking pString (which contains the string "test") and copying it directly to vToate. 只是采用pString(包含字符串“test”)并将其直接复制到vToate。 So what you return is the string "test". 所以你返回的是字符串“test”。

There are numerous ways to concatenate various data types to a single string in C++, but the one I find the most simple is using std:stringstream: 在C ++中,有多种方法可以将各种数据类型连接为单个字符串,但是我发现最简单的一种方法是使用std:stringstream:

stringstream ss;
ss << vTest << " " << vTest;
char* vTmp = ss.str();
cout << vTmp;

It looks you're unclear about how to use variadic macros. 看起来你不清楚如何使用可变参数宏。 You forgot to call va_arg to get each next element. 你忘了调用va_arg来获取每个下一个元素。 You also need a length or sentinel value, so you can know when there aren't any more arguments. 您还需要一个长度或标记值,这样您就可以知道何时没有任何参数。 It seems like you want this: 看来您想要这样:

char *copy(char *str, ...)
{
    va_arg ap;
    va_start(str, ap);
    int len = 0;
    char *sp;
    for(sp=str; sp; sp=va_arg(ap, char*))
        len+=strlen(sp);
    va_end(ap);
    va_start(ap);
    char *dst = new char[len+1];
    int pos = 0;        
    for(sp=str; sp; sp=va_arg(ap, char*)){
        memcpy(dst+pos, sp, strlen(sp));
        pos+=strlen(sp);
    }
    va_end(ap);
    dst[pos] = '\0';
    return dst;
}

Which you would then call: 然后你会打电话给:

char *str = copy("foo", " ", "bar", NULL);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM