我正在开发一个C ++应用程序,它将从一组数据库字段构建一个固定长度的记录。我正在编写一个函数,它将输出记录接受为char*
,要写入的字符串以及字段的总长度。该函数的目的是将字符串复制到char指针的当前位置,然后用空格填充剩余的长度。这是我正在做的简化示例。
void writeOut(char* output, string data, const int length) {
if ((int) data.size() > length) {
//Just truncate it
data = data.substr(0, length);
}
int index = 0;
while (index < (int) data.size()) {
*output++ = data[index++];
}
while (index++ < length) {
*output++ = ' ';
}
}
int test() {
char output[100];
writeOut(output, "test1", 10);
writeOut(output, "test2", 10);
writeOut(output, "test3test4test5", 10);
cout << output;
}
我希望看到类似的东西。
test1 test2 test3test4
相反,我得到的只是......
test3test4
因此它在函数内递增char*
,但仅在函数内递增。当函数结束时,char*
正好在它开始的位置。是否可以以在调用函数中更新指针的方式传递指针?
如果你不能说,我对C ++很陌生。任何建议将不胜感激。
答案 0 :(得分:8)
由于您没有通过引用传递参数,编译器会创建指针的副本并相应地在函数内修改副本。
将您的功能签名更改为以下内容。
void writeOut(char*& output, string data, const int length)
如果您不打算修改string
,也可以考虑将const string&
传递给{{1}}。
答案 1 :(得分:8)
您想要将char **传递给该函数。
void writeOut(char** output, string data, const int length) {
if ((int) data.size() > length) {
//Just truncate it
data = data.substr(0, length);
}
int index = 0;
while (index < (int) data.size()) {
*(*output)++ = data[index++];
}
while (index++ < length) {
*(*output)++ = ' ';
}
}
int test() {
char output[100];
char *pos = output;
writeOut(&pos, "test1", 10);
writeOut(&pos, "test2", 10);
writeOut(&pos, "test3test4test5", 10);
cout << output;
}
(手头没有编译器,但应该工作)
答案 2 :(得分:6)
你可以通过保留一个新的字符指针来完成你所追求的目标,但你不能增加“输出”变量,然后再次使用不增加(在你的cout行中)。
例如,您可以执行以下操作:
char* writeOut(char* output, string data, const int length) {
if ((int) data.size() > length) {
//Just truncate it
data = data.substr(0, length);
}
int index = 0;
while (index < (int) data.size()) {
*output++ = data[index++];
}
while (index++ < length) {
*output++ = ' ';
}
return output; // return the new position here!
}
int test() {
char output[100];
char *outputLocation = output;
outputLocation = writeOut(outputLocation, "test1", 10);
outputLocation = writeOut(outputLocation, "test2", 10);
outputLocation = writeOut(outputLocation, "test3test4test5", 10);
cout << output;
}
答案 3 :(得分:2)
发生的事情是,每次你拨打writeOut时,你都会将相同的位置(即开始)传递给电话。
您需要的是另一个在调用writeOut时移动的变量。有几种方法可以做到这一点:
第一个也是“最简单”的选项是在“引用指针”中传递你传递的参数:
void writeOut (char *& output, ...) {
// ...
}
int test () {
char output[100];
char * p = output;
writeOut (p, "test1", 10);
writeOut (p, "test2", 10);
// ...
}
这是有效的,因为参数output
现在是main主体中指针p
的别名。因此,对writeOut中的参数所做的更改也发生在p
。
下一个最简单的选择是每次都返回新位置:
char * writeOut (char * output, ...) {
// ...
return output;
}
int test () {
char output[100];
char * p = output;
p = writeOut (p, "test1", 10);
p = writeOut (p, "test2", 10);
// ...
}
这里,参数在函数内被修改,我们每次都在main中更新p
。
最后,您可以在writeOut上创建一个指向指针的参数:
void writeOut (char ** output, ...) {
// ...
while (index < (int) data.size()) {
**output = data[index++];
(*output)++;
}
// ...
}
int test () {
char output[100];
char * p = output;
writeOut (&p, "test1", 10);
writeOut (&p, "test2", 10);
// ...
}
这里发生的是我们的参数不再指向'输出',而是指向'p'的地址。在我考虑之前,我几乎肯定会选择参考选项。
答案 4 :(得分:0)
您需要通过引用传递。
答案 5 :(得分:0)
要理解的重要一点是,函数的参数是通过值传递的,即它们被复制。
函数的第一个参数是指针,换句话说是指向内存的数字。当您调用该函数时,此数字将从test()
复制到printOut()
,这允许printOut()
访问test()
分配的内存。
正如其他人所建议的那样,您可以返回指针的新值,也可以将其作为参考传递。否则,您可以使用指向指针的指针,这将允许您更新printOut()
中的指针。
答案 6 :(得分:0)
为什么不使用snprintf?
int writeOut(char *output, char *data, int length)
{
return snprintf(output, length + 1, "%-*s", length, data);
}
void test()
{
char output[100];
char *outputLocation = output;
outputLocation += writeOut(outputLocation, "test1", 10);
outputLocation += writeOut(outputLocation, "test2", 10);
outputLocation += writeOut(outputLocation, "test3test4test5", 10);
printf("%s\n", output);
}
我认为这更容易。我想,由你决定。