跳转至

输入输出

前置知识

目标

把用到的输入全部捋一遍,掌握但不乱用

cin, cout

C++的输入输出

string s1, s2;
char c;

cin >> s1 >> s2;
cout << s1 << ' ' << s2 << '\n';

scanf, printf

C语言的输入输出

int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", a + b);

// 占位符对应关系
int %d
double %lf
char %c
long long %lld

控制精度

保留 2 位小数点
printf("%.2lf", a);

cout.flags(ios::fixed);
cout.precision(2);
cout << a << '\n';

cout 默认 输出 6 位精度

image-20240708150257981

// 控制精度,但这个不是小数点后几位的意思

image-20240708150437891

加上,cout.flags(ios::fixed); 才可以控制小数点后几位

image-20240708150500368

后面的cout,都是相同的格式控制

image-20240708150842549

取消格式控制,添加 cout.unsetf(ios::fixed);

image-20240708150942554

还可以写成,cout.setf(ios::fixed);

image-20240708151008609

控制场宽

 8个字符宽度
printf("%8d", a);  // 靠右
printf("%-8d", a);  // 靠左

cout << setw(8) << x << setw(8) << x;  // 靠右
cout << left << setw(8) << x << left << setw(8) << x;  // 靠左

默认靠右

image-20240708151316128

强制靠左

image-20240708151401963

读入字符串

C 语言风格的字符串,char s[110];

C++ 风格的字符串,string s;

// 字符串,分为字符数组和 string
char s[110];
scanf("%s", s);
// 或者 cin >> s; 也是可行的,但不推荐这样用,没有明确说明

string s;
cin >> s;

// string 转换成 C 语言风格字符串
string s;
s.c_str();

读入二维字符数组

读入二维字符数组,切不可两层循环

char g[110][110];
for (int i = 0; i < n; i++) scanf("%s", g[i]);

读入一整行

// 适用于一行字符串,中间有空格,空格也要读进来的情况
// getline效率低下,非此处情况,不要随便使用
string s;
getline(cin, s);

while(cin >> x)

// 有的时候,会给你一行数字,每个数字用空格隔开,但没有具体告诉你有几个
while (cin >> x) {

}

while (scanf("%d", &x) == 1) {

}

sscanf

// 这个在关键的时候,可以救命
// 比如,网络连接,这道题目,读入 a.b.c.d:e 的格式,判断合法性
// 正常做,也是可以的,读入字符串,然后一个一个拆。但是,情况非常多,非常考验代码能力
scanf("%s", s);
a = -1, b = -1, c = -1, d = -1, e = -1;
sscanf(s, "%d%c%d%c%d%c%d%c%lld", &a, &dot1, &b, &dot2, &c, &dot3, &d, &dot4, &e);
#include<stdio.h>

int main()
{
    char ar[20] = "User M 19 1.85";

    char str[10];
    char ch;
    int i;
    float f;

    /* Calling sscanf() to read multiple values from a char[] array and store each value in matching variable */
    sscanf(ar, "%s %c %d", &str, &ch, &i, &f);


    printf("The value in string is : %s ", str);
    printf("\n");

    printf("The value in char is : %c ", ch);
    printf("\n");

    printf("The value in int is : %d ", i);
    printf("\n");

    printf("The value in float is : %f ", f);

    return 0;
}

// 输出
The value in string is : User
The value in char is : M
The value in int is : 19
The value in float is : 1.850000

sprintf

#include<stdio.h>

int main()
{
    char target[20];

    char name[10] = "Andrea";
    char gender  = 'F';
    int age = 25;
    float height = 1.70;

    printf("The name is : %s", name);
    printf("\n");
    printf("The gender is : %c", gender);
    printf("\n");
    printf("The age is : %d", age);
    printf("\n");
    printf("The height is : %f", height);


    /* Calling sprintf() function to read multiple variables and store their values in a char[] array i.e. string.*/
    sprintf(target, "%s %c %d %f", name, gender, age, height);


    printf("\n");
    printf("The value in the target string is : %s ", target);

    return 0;
}

// 输出
The name is : Andrea
The gender is : F
The age is : 25
The height is : 1.700000
The value in the target string is : Andrea F 25 1.700000

stringstream

// 把整型+字符,直接输出到 stringstream里,然后转换成 string使用,这样拼接非常简便
int a, b, c, d, e;
stringstream ss;
ss << a << '.' << b << '.' << c << '.' << d << ':' << e;
string s = ss.str();

img

    // 数据类型转换,例如,将 int 转换成 string
    stringstream sstream;
    string strResult;
    int nValue = 1000;

    // 将int类型的值放入输入流中
    sstream << nValue;
    // 从sstream中抽取前面插入的int类型的值,赋给string类型
    sstream >> strResult;

    cout << "[cout]strResult is: " << strResult << endl;
    printf("[printf]strResult is: %s\n", strResult.c_str());

    // 多个不同数据类型的拼接,例如 int、string,交叉的拼接成一个 string
    int a, b, c, d, e;
    stringstream ss;
    ss << a << '.' << b << '.' << c << '.' << d << ':' << e;
    cout << ss.str() << '\n';

    // 多次操作之间,stringstream 需要清空
    stringstream sstream;
    sstream.str("");
    // 或者
    sstream.clear();

当输入输出超过 10 万的时候

// 超过 1e5,就使用 scanf, printf
// 否则会因为 cin, cout,导致超时

// 当然,就是想用 cin cout,也有办法
ios::sync_with_stdio(false);
cin.tie(nullptr);

// 如果这样做了,则需全程使用 cin cout,不可与scanf混用

输出换行符

// 这个就是个人喜好了,细节上有一个 flush operation 的区别
// 在普及组,没有区别,想用哪个用哪个

img

从文件输入输出

// freopen一定是在复赛前,非常熟练使用,主要是调试要熟练
// 从文件输入输出,还有别的写法,但下面这个写法就稳过好记
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);

cin cout的加速

    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

总结

平时按规范写法进行练习,比赛的时候才是稳的

参考

C - sscanf() and sprintf() - Decodejava.com

C++编程语言中stringstream类介绍-CSDN博客

C++ I/O Flags

有关ios::sync_with_stdio(false);和 cin.tie(nullptr);的介绍与意义