有没有办法永久设置std::setw操纵器(或其功能width)?看这个:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <iterator>
int main( void )
{
int array[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256 };
std::cout.fill( '0' );
std::cout.flags( std::ios::hex );
std::cout.width( 3 );
std::copy( &array[0], &array[9], std::ostream_iterator<int>( std::cout, " " ) );
std::cout << std::endl;
for( int i = 0; i < 9; i++ )
{
std::cout.width( 3 );
std::cout << array[i] << " ";
}
std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
跑完后,我看到:
001 …Run Code Online (Sandbox Code Playgroud) 我最近被这样的事实所困扰:ios_base::width和/或setw操纵器必须在写入流的每个项目时重置.
也就是说,你必须这样做:
while(whatever)
{
mystream << std::setw(2) << myval;
}
Run Code Online (Sandbox Code Playgroud)
而不是这个:
mystream.width(2);
while(whatever)
{
mystream << myval;
}
Run Code Online (Sandbox Code Playgroud)
好的.
但有谁知道为什么做出这个设计决定?是否有一些我缺失的理由,或者这只是标准的一个黑暗角落?
其他流格式修饰符(如链接的SO问题中所述)是"粘性",而setw不是.
有没有办法制作setw和setfill填充字符串的末尾而不是前面?
我有一种情况,我打印这样的东西.
CONSTANT TEXT variablesizeName1 .....:number1
CONSTANT TEXT varsizeName2 ..........:number2
Run Code Online (Sandbox Code Playgroud)
我想添加一个可变数量'.'的结尾
"CONSTANT TEXT variablesizeName#"所以我可以":number#"在屏幕上排队.
注意:我有一个数组,"variablesizeName#"所以我知道最广泛的情况.
要么
我应该做手工设置setw这样的
for( int x= 0; x < ARRAYSIZE; x++)
{
string temp = string("CONSTANT TEXT ")+variabletext[x];
cout << temp;
cout << setw(MAXWIDTH - temp.length) << setfill('.') <<":";
cout << Number<<"\n";
}
Run Code Online (Sandbox Code Playgroud)
我想这可以做到这一点,但感觉有点笨重.
想法?
我试图让我的输出看起来像这样:
size time1 time2
-------------------------------
10 4 8
100 48 16
1000 2937 922
10000 123011 3902
100000 22407380 830722
Run Code Online (Sandbox Code Playgroud)
我知道我需要使用setw(),setfill()和left.但是,我的尝试一直给我不正确的输出.这是我的代码的一个例子:
std::cout << "size" << std::setw(20) << "time" << std::setw(20) << "time2\n";
std::cout << std::setfill('-') << std::setw(60) << "-" << std::endl;
run = 10;
for(int i = 0; i < 5; i++) {
std::cout << run;
run *= 10;
std::cout << std::setw(20) << std::left << time1[i];
std::cout << std::setw(20) << std::left << time2[i] << …Run Code Online (Sandbox Code Playgroud) 一些标准iomanip函数需要参数.
我想知道这是如何实现的,例如,我可以用函数做类似的事情吗?这真的是我需要这个答案的解决方案,但我无法弄清楚如何做到这一点.
当我查看setw函数的定义时,例如在http://en.cppreference.com中,它将返回类型列为"未指定",它也只列出一个参数,而不是stream&参数.这是如何运作的?
这个问题有一个很好的答案,但对于个人提出这个问题; 此答案仅在与以下功能结合使用时才有用ios_base:
我正在使用std :: stringstream将固定格式字符串解析为值.但是,要解析的最后一个值不是固定长度.
要解析这样的字符串,我可能会这样做:
std::stringstream ss("123ABCDEF1And then the rest of the string");
ss >> std::setw(3) >> nId
>> std::setw(6) >> sLabel
>> std::setw(1) >> bFlag
>> sLeftovers;
Run Code Online (Sandbox Code Playgroud)
但是如何设置宽度以便输出字符串的其余部分?
通过反复试验,我发现这样做有效:
>> std::setw(-1) >> sLeftovers;
Run Code Online (Sandbox Code Playgroud)
但是正确的方法是什么?
是实现定义还是标准建议流的默认填充字符?
示例代码:
#include <iostream>
#include <iomanip>
#include <sstream>
int main ()
{
std::stringstream stream;
stream << std::setw( 10 ) << 25 << std::endl;
std::cout << stream.str() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
同 clang++ --stdlib=libstdc++
$ clang++ --stdlib=libstdc++ test.cpp
$ ./a.out | hexdump
0000000 20 20 20 20 20 20 20 20 32 35 0a 0a
000000c
$
Run Code Online (Sandbox Code Playgroud)
同 clang++ --stdlib=libc++
$ clang++ --stdlib=libc++ test.cpp
$ ./a.out | hexdump
0000000 ff ff ff ff ff ff ff ff 32 35 0a 0a
000000c …Run Code Online (Sandbox Code Playgroud) 我的问题显示在以下最小示例中:
#include <iostream>
#include <string>
#include <iomanip>
int main()
{
int width = 15;
std::cout << std::left;
std::cout << std::setw(width) << "Prints well" << std::setw(width) << "This too" << '\n';
std::cout << std::setw(width) << "\u221E" << std::setw(width) << "This not?" << '\n';
std::cout << std::setw(width+2) << "\u221E" << std::setw(width) << "This is good" << '\n';
}
Run Code Online (Sandbox Code Playgroud)
使用 g++ 编译,它打印:
Prints well This too
? This not?
? This is good
Run Code Online (Sandbox Code Playgroud)
因此,unicode 符号似乎使用了 setw 中的 3 个空格而不是一个。有没有一种简单的方法可以解决这个问题,事先不知道字符串中是否会包含 unicode 字符?
所以我刚刚开始学习 C++,我很好奇它是否是一种用 cout 格式化输出的方法,这样它看起来会很漂亮并且按列结构化
例如。
string fname = "testname";
string lname = "123";
double height = 1.6;
string fname2 = "short";
string lname2 = "123";
double height2 = 1.8;
cout << "Name" << setw(30) << "Height[m]" << endl;
cout << fname + " " + lname << right << setw(20) << setprecision(2) << fixed << height << endl;
cout << fname2 + " " + lname2 << right << setw(20) << setprecision(2) << fixed << height2 << endl
Run Code Online (Sandbox Code Playgroud)
输出如下所示:
Name …Run Code Online (Sandbox Code Playgroud) 我正在尝试从字符串中以十六进制表示法读取字节。字节可能会或可能不会被空格分隔,例如,这" 00 ffab c "是一个有效的例子,应该导致读取 4 个字节,0x00、0xff、0xab 和 0x0c。问题是跳过空格但只读取两个相邻的数字(如果存在)。
如果输入是来自一个文件,任务将是一样容易while(fscanf(f, "%2d", &i) == 1) ...,因为sscanf空白,读出位置由基础跟踪跳跃FILE,和宽度仅应用到物品的最大场读,不包含空白原始输入字符。但是从字符串中读取时无法进行位置跟踪;我需要使用%n格式转换说明符,它将到目前为止通过此调用读取的字符数存储到关联变量中,例如scanf(f, "%2d%n", &i, &readIncr),并通过添加相应的增量手动维护读取位置。
这有点麻烦,因此我想使用std::istringstreamwhich来跟踪底层字符串中的位置。
但是在输入流上设置宽度并没有预期的(和预期的)效果;下面是一个最小的演示;为简单起见,我使用十进制整数。输入字段宽度的文档和示例很少。
难道我做错了什么?我这个用例根本不是故意的?
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdio>
using namespace std;
int main()
{
const char *s = " 1234";
int i;
istringstream is(s);
if (is >> setw(2) >> i)
{
cout << "stringstream i: " << i << '\n';
} …Run Code Online (Sandbox Code Playgroud)