我得到了以下代码:
char* writeSpace(int i)
{
fputs(" " + (30-i), stdout);
}
printf("#%i key: %s%svalue: %s%s value2: %s", id, key, writeSpace(10), value, writeSpace(8), value2);
我的输出应该类似于:
#1 key: foo value: bar value2: foobar
但事实并非如此。它看起来像:
#1 key: foo(null)value: bar(null)value2: foobar(null)
我的代码出了什么问题?
答案 0 :(得分:4)
您已宣布writeSpace()
返回char*
,但您尚未从中返回任何内容。
答案 1 :(得分:4)
嗯,你是fput
所有这些空间到控制台,所以你先得到它们。
然后你输出其他所有东西,所以你接下来就得到了。
也许您的意思是writeSpace
返回一个C风格的字符串,而不是将其打印到控制台。
但请务必为此分配空间!由于内存缓冲区的所有权有点隐蔽,因此最好在函数外部分配。
void writeSpace(char* buf, int i) {
fputs(" " + (30-i), buf);
}
char spaceBuf1[30];
writeSpace(spaceBuf1, 10);
char spaceBuf2[30];
writeSpace(spaceBuf2, 8);
printf("#%i key: %s%svalue: %s%s value2: %s",
id, key, spaceBuf1, value, spaceBuf2, value2);
并考虑使用实际 C ++功能,如iostreams和std::string
。这会容易得多:
std::cout << "#" << id << " "
<< " key: " << std::setw(30) << key
<< " value: " << std::setw(30) << value
<< " value2: " << value2;
我建议these resources学习惯用语C ++。
答案 2 :(得分:0)
你的writeSpace
函数没有返回一个新字符串(即使你已经这样声明了)但是直接写入终端。由于您在printf
调用中将其称为参数,因此首先调用writeSpace
,打印其内容,然后printf
打印其内容。你应该这样做:
char* writeSpace(int i)
{
char *ret = NULL;
asprintf(ret, " " + (30-i));
return ret;
}
当然,这需要你free
内存(否则你会有内存泄漏)。你可以这样做:
char *spaces = writeSpace(10);
printf("%s%i", spaces, 42);
free(spaces);
另一种方法是使用函数本身在下次调用时清理的静态变量:
char* writeSpace(int i)
{
static char *ret = NULL;
if (ret != NULL) free(ret);
asprintf(ret, " " + (30-i));
return ret;
}
但是这样做的缺点是你只能在writeSpace
个参数中使用printf
的一个调用,因为第二个调用将清除前一个调用的内存。仍然可能是你想要的。
+ (30-i)
部分是邪恶的。你可能想要的是这个:
asprintf(ret, "%*s", i, ""); // Prints i spaces
答案 3 :(得分:0)
如果你想格式化变量ws'并且你必须使用普通的C你可以使用这样的格式字符串(%* c,其中*是ws的数量,c代表要设置的字符(在这种情况下为'')当然)):
sprintf(buffer, "%*cafterspace", 30, ' '); // Will print 30 ws and then "afterspace".
sprintf(buffer, "%*cafterspace", 15, ' '); // Will print 15 ws and then "afterspace".
但是你仍然要像Tomalak解释的那样准备一个缓冲区!
答案 4 :(得分:0)
提供的其他答案有正确的答案。但是,我想尝试添加一些您所看到的症状的解释,以帮助您将来避免它们。
执行printf语句时:
printf("#%i key: %s%svalue: %s%s value2: %s", id, key, writeSpace(10), value, writeSpace(8), value2);
两个writeSpace()方法调用在printf本身执行任何操作之前执行。原因是这些方法的返回值用作printf方法的参数。所以上面一行代码的执行顺序是:
这就是为什么你看到开头打印的空格,以及你看到输出中出现“(null)”的原因。
因此,这里学到的教训是,在程序执行期间,方法的参数在调用方法本身之前得到解决。