← 返回 C++ 学习记录

C++ JOURNAL / 输入输出与格式

C++ 格式输出与特殊输入

setw、两位小数,以及逗号分隔输入为什么会读错。

按我的学习记录整理 · 示例用于帮助理解
这篇记录里

iomanip 与对齐

包含 <iomanip> 后,可以使用 setw、setprecision 等工具。

#include <iostream>
#include <iomanip>
using namespace std;
int main() {
    cout << "|" << right << setw(15) << 12 << "|" << endl;
    cout << "|" << left << setw(15) << 12 << "|" << endl;
    cout << fixed << setprecision(2) << 0.1323 << endl;
    return 0;
}

right 右对齐,left 左对齐;数字旁会补空格。最后一行输出 0.13。

setw 不是一直有效

setw(15) 设置下一项的最小字段宽度,内容超过 15 个字符也不会被截断。对这里的普通数字、字符串输出,宽度使用后就重置;想给两个数都设宽度,要分别写:

cout << setw(15) << a << setw(15) << b;

left、right、fixed、setprecision、hex、dec 等状态通常会保留在对应的流中,直到再次更改。不要把它们和 setw 的范围混为一谈。

fixed 和 setprecision

fixed << setprecision(2) 表示固定小数格式,小数点后保留两位,输出会按精度进行舍入。不加 fixed 时,setprecision 通常控制有效数字位数,不能直接当成“小数点后几位”。

我曾经写过 printf("%lf.2\n", a+b);,那不是保留两位小数;C 的写法见格式化输出补充。

string 和 %s

“%s 不是字符串的格式吗,为什么不能定义成 string?”

string 是 C++ 的类型;%s 是 printf/scanf 的格式说明符,不是类型名。C 的 %s 对应字符数组中的 C 风格字符串,不能把 std::string 对象直接当作它需要的参数。当前 C++ 学习中用 cin、cout 读写 string 即可。

那个逗号分隔的输入

我做过的输入形式是:

1,0xF,abcdefghij,0.1323

依次是十进制整数、十六进制整数、10 个字符的字符串、浮点数。用 char 变量读取逗号,是我用过的方法。

以下是基于已经接触过的循环和字符读取整理的完整示例,只处理题目约定的恰好 10 个非空白字符:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main() {
    int a, b;
    char x, ch;
    string c;
    double d;
    cin >> a >> x;
    if (x != ',') return 0;
    cin >> hex >> b >> x;
    if (x != ',') return 0;
    for (int i = 0; i < 10; i++) {
        cin >> ch;
        c += ch;
    }
    cin >> x;
    if (x != ',') return 0;
    cin >> dec >> d;
    if (!cin) return 0;
    cout << dec << a << " " << b << " " << c << " "
         << fixed << setprecision(2) << d << endl;
    return 0;
}

输出 1 15 abcdefghij 0.13。c += ch 是把这个字符接到字符串末尾;!= 表示不相等;!cin 用于检查输入是否失败。这些检查是整理时补上的保护,不代表新增的练习经历。若题目改成不定长字符串,需要另行调整读取方式。

为什么 cin >> c 会吞掉逗号

cin >> string 默认以空白字符(如空格、换行)为边界,不把逗号当作分隔符。直接读上述输入中的 c,可能把 abcdefghij,0.1323 一起读走,后面的读取自然就不符合预期。

另外,cin >> hex 改的是 cin;不会自动改变 cout 的进制。需要分别设置。

返回全部学习记录 ↗