设置带空格的字符串格式
Format string with spaces
我正在尝试用C++制作一个优雅的日志记录系统。我目前正在使用printf()
,尽管cout
也可以是一个选项。
我想要实现的是像这个
console_log( "ClassName", "funcName", "Message." );
我目前的代码很简单:
static void console_log( const std::string & className, const std::string & funcName, const std::string & message ) {
printf( "%s : %s : %sn", className.c_str(), funcName.c_str(), message.c_str() );
}
它打印得很好,就像这个
// For example:
console_log( "MenuPanel", "selectedThisButton", "Something happened." );
console_log( "MenuPanel", "selectedAnotherButton", "Another thing happened." );
// Output:
MenuPanel : selectedThisButton : Something happened.
MenuPanel : selectedAnotherButton : Another thing happened.
然而,我希望它以类似表格的方式打印,其中所有"列"都正确对齐。例如:
MenuPanel : selectedThisButton : Something happened.
MenuPanel : selectedAnotherButton : Another thing happened.
如何使第一列和第二列的宽度/字符数完全相同,并在必要时添加空格?它不需要是动态的。将"列"设置为16个字符即可。
不过,我不希望使用任何第三方libs来实现如此简单的功能。如果可能的话,没有boost
。
我会使用I/O流而不是C样式的printf
,对于打印具有特定宽度的东西(任何类型),您可以包括<iomanip>
并设置字段宽度:
some_stream << std::setw(MY_WIDTH) << whatever;
示例:
#include <iostream>
#include <iomanip>
int main()
{
std::cout << std::setw(10) << "hi";
}
输出:
hi
如果你采用"保持简单"的方式,你可以替换:
printf( "%s : %s : %sn", className.c_str(), funcName.c_str(),
message.c_str() );
至
printf( "%30s : %30s : %30sn", className.c_str(), funcName.c_str(),
message.c_str() );
无论您喜欢什么宽度,都可以查看printf文档中的对齐修饰符。
一般的解决方案相当复杂,但如果您可以假设固定宽度字体(其中每个字符具有相同的宽度),并且知道前面每列的宽度,类似于:
std::string rPad( std::string const& original, int minWidth )
{
return original
+ std::string(
std::max( minWidth - static_cast<int>( original.size() ), 0 ),
' ' );
}
void console_log(
std::string const& className,
std::string const& funcName,
std::string const& message )
{
std::cout << rPad( className, classNameWidth )
<< " : " << rPad( funcName, funcNameWidth )
<< " : " << rPad
<< std::endl;
}
或者,你可以做一些类似的事情:
void console_log(
std::string const& className,
std::string const& funcName,
std::string const& message )
{
std::cout << alignedText( classNameWidth ) << className
<< " : " << alignedText( funcNameWidth ) << funcName
<< " : " << message << std::endl;
}
操纵器alignedText
通常很有用无论如何都应该把它放在你的工具箱里:
class alignedText
{
mutable std::ostream* myOwner;
mutable std::ostream::fmtflags myFlags;
int myWidth;
public:
alignedText( int width ) : myOwner myWidth( width ) {}
~alignedText()
{
if ( myOwner != nullptr ) {
myOwner->flags( myFlags );
}
}
void set( std::ostream& dest ) const
{
if ( myOwner == nullptr ) {
myOwner = &dest;
myFlags = myOwner->flags();
}
dest.setf( std::ios_base::left, std::ios_base::adjustfield );
dest.width( myWidth );
}
friend std::ostream& operator<<( std::ostream& dest, alignedText const& manip )
{
manip.set( dest );
return dest;
}
};
(虽然使用printf
也可以做同样的事情,但结果可读性差得多,完全无法维护,当然,你有printf
的一般脆弱性。)
相关文章:
- 字符串::格式有什么用. 我也没有在互联网上得到它
- 如何检查字符串格式在读取C++文本文件时是否有效?
- 十进制到八进制递归C++.以标准::字符串格式输出
- 如何从字符串格式中提取 3 个整数"v%d.%d.%d"?
- 查找可变参数列表的字符串格式指定符
- 字符串格式替换为 snprintf 中字符中的值
- 使用堆栈将字符串格式的十进制转换为双精度
- 使用字符串格式限制十六进制数字的数量
- 视觉C++:字符串格式
- C++字符串格式实现错误
- 如何在Xcode中将长双精度转换为字符串格式?或如何解决错误"use of undeclared identifier 'to_string' "
- C++以字符串格式 YYYYMMDD 减去天数
- 如何在windows和linux中使用相同的宽字符串格式
- 如何将标准::字符串格式的 JSON 解码为 Boost 属性树
- C++格式的字符串格式
- 使用C++将任何形式的日期-时间字符串格式更改为美国日期-时间格式
- 使用C/C++设置字符串格式
- 如何创建以字符串格式使用给定变量文本的宏(或其他工具)
- 如何转换?toString() 的 C 字符串格式
- 用字符串格式运算符替换C++字符串