C++ ACM模式输入输出

C++ ACM模式输入输出

以下我们都以求和作为题目要求,来看一下各种输入输出应该怎么写。

1 只有一个或几个输入

输入样例:

3 5 7

输入输出模板:

int main() {
    int a, b, c;
 		// 接收有限个输入
    cin >> a >> b >> c;
  	// 输出结果
    cout << a+b+c << endl;
}

2 先给元素个数,再给元素

先给行数T,再给出T行

输入样例:

3
3 5 7
6 8 9
12 9 5

输入输出模板:

int main() {
    int T;
    vector<int> res;
  	// 拿到输入行数T
    cin >> T;
  	// 接收T行输入
    while (T--) {
        int a, b, c;
        cin >> a >> b >> c;
        res.push_back(a+b+c);
    }
  	// 输出结果
    for (int n : res) {
        cout << n << endl;
    }
}

先给数组元素个数,再给一行数组

n, m分别是接下来要给的两个数组元素的个数,输入样例:

5 2
1 4 2 6 5
2 3

接收输入代码:

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> nums(n);
    for (int i=0; i<n; ++i) cin >> nums[i];
    vector<int> lens(m);
    for (int i=0; i<m; ++i) cin >> lens[i];
}

3 多组输入,读到文件结束符EOF为止

不直接告知有多少组输入,而是由EOF来判断。

方法一

cin 读到有数据输入时会返回非0,而读到文件结束符时会返回0,结束while循环。

int main() {
    int a, b;
    vector<int> res;
    while (cin >> a >> b) {
        res.push_back(a+b);
    }
}

方法二

scanf 读到文件结束符时会返回-1,而-1的补码表示恰好是全1,从而用按位取反得到0,此时结束 while 循环。

int main() {
    int a, b;
    vector<int> res;
    while (~scanf("%d%d", &a, &b)) {
        res.push_back(a+b);
    }
}

4 字符串的输入

同样有 cinscanf 两种方法

方法一

int main() {
    const int N = 100;
    char s[N];
    scanf("%s", s);
}

方法二:

int main() {
    string s;
    cin >> s;
    cout << s << endl;
}

字符串的输入有几点需要注意:

  • C/C++ 中读入的字符串时包含结束符 \0 的,我们需要的字符数组的长度要比真正的字符数加一;
  • cinscanf 两种读入方式都会忽略行首和行位的空格。

5 格式化输入scanf

情况一

当我们面对这样的字符串输入:214+1352,要来计算两数之和时,cin 就不好使了。需要我们的格式化输入 scanf

int main() {
    int a, b;
    scanf("%d+%d", &a, &b);
    cout << a+b << endl;
}

情况二

如果我们会接收到一排数字,而我们想要计算其中每单个数字的和,我们也可以借助格式化输入的 %1d 来实现,它能一位一位地读入标准输入:

int main() {
    int a;
    int sum = 0;
    while (~scanf("%1d", &a))
        sum += a;
    cout << sum << endl;
}

标准化输入函数 scanf 还有许多奇妙的用法,有兴趣可以自行查阅相关资料。

6 ASCII码

  1. 可以根据 ASCII 码的区间来判断某个字符是数字还是大小写字母等(比如通过与 'a''z'等 ASCII 码值的大小关系)。
  2. 根据数字字符的 ASCII 码得到数字本身的值:减去 0 的 ASCII 码 char c='3'; int a = c-'0',整型变量 a 的值为 3。

7 整行读取字符串

当我们不确定一行中是否有空格等特殊字符,我们可以使用 getline 进行整行读取:

int main() {
    string s;
    getline(cin, s);
    cout << s << endl;
}

默认以回车作为结束,如果需要自定义,可:

getline(cin, s, '?');

补充知识

string与char数组

  1. char[] 在C/C++中均可用,string仅在C++中可用,且需要 #include ,一般称 char[] 为 C 风格的字符串,称 string 为 C++ 风格的字符串
  2. string 通常用 cin 读入,char[] 通常用 scanf 读入。scanf 不可以用来读入 string
  3. char[] 构造 string:string str(s);
  4. string 转换为 char[]:s = str.c_str();
  5. 一般直接 cin 读取 string 会很慢,可以读到 char[] 中,再构造为 string

printf/scanf 与 cout/cin

在读取数据量巨大(经验值为大于1e5个正数以上)时,cin 会很慢,这是因为 cin/cout 需要与 scanf/printf 同步。

解决方法:

  1. 改用 scanf/printf

  2. 关闭同步,改善效率(有的编译器可行,有的无效)

    cin.tie(0); cout.tie(0); ios::sync_with_stdio(0);
    
  3. cout << endl; 除了换行之外,还会清空缓存区,而清空缓存区这件事情会耗时很久,因此为了提高速度,一般直接:cout << "\n";,会快很多

保留小数位数

  1. 如保留 3 位小数:printf("%.4f\n", a);, 此种方法会自动的四舍五入。
  2. 一位小数四舍五入成整数:float a = 2.7; printf("%d\n", int(a+0.5));

Ref:

https://www.bilibili.com/video/BV1ri4y1L7f7?from=search&seid=11052128712667700362&spm_id_from=333.337.0.0

你可能感兴趣的:(C++,c++,c语言,开发语言)