Skip to content

输入输出相关

stdio

standard input / output 标准输入/输出

1. 输出固定小数位数

CPP

C++
1
2
3
4
5
#include<iostream>
#include<iomanip>

// without std::fixed, output will be scientific notation(科学计数法) format.
std::cout<<std::fixed<<std::setprecision(5)<< number<<std::endl;
C
C
1
2
#include<stdio.h>
printf("%.5lf",number);

2. 重载操作符 <<

Overload << can't be a member function, Because It's a Linked-Like coding (链式编程). It will always return std::ostream&

  1. Use friend function define in class. Also can declare it outside as global function,
  2. Use class's print function to access private members.
  3. Use transition-timing-function (过渡函数):
    C++
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
     class Test{
        std::ostream& Output(std::ostream& out){
            return out<<"data: "<< data;
        }
    
        Test data;
    }
    
    std::ostream& operator<< (std::ostream& out, Test& test){
        return test.Output(out);
    }
    

3. 格式化字符串

原始人操作

传入参数列表的是一个 (format, ...), 用 va_list 来接住参数

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <cstdio>
#include <cstdarg>

void foo(const char* format, ...)
{
    // do this iterate to get length
    va_list arg_ptr;
    va_start(arg_ptr, format);
    int size = vsnprintf(NULL, 0, format, arg_ptr);
    va_end(arg_ptr);


    // 注意: 在用`vsnprintf` 获取长度后,先`va_end(arg_ptr)`, 然后需要再次使用一轮`va_...`函数来获取可变参数, 否则会产生乱码.
    // Restart va_list to reuse the arguments
    va_start(arg_ptr, format);
    char* buf = new char[size + 1];
    vsnprintf(buf, size + 1, format, arg_ptr);
    va_end(arg_ptr);

    // Don't forget to free the memory!
    delete[] buf;
}
C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <cstdarg>
#include <cstdio>

void foo(const char* format, ...)
{
    va_list arg_ptr;
    va_start(arg_ptr, format);
    vprintf(format, arg_ptr); // works
    va_end(arg_ptr);
} 

Modern C++

C++
1
2
3
4
5
std::foramt("{} {}", arg1, arg2);  // C++20
std::println("{} {}", arg1, arg2);  // C++23

fmt::foramt("{} {}", arg1, arg2);  // `fmt` 3rd library required
std::cout<<  fmt::foramt("{} {}", arg1, arg2) << '\n';

4. 一种方便的调试打印方式

A debug/print class which maybe some kinda useful

PS: 4202年了, debug打印不应该由ai自动生成了么?

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

struct debug {
    std::ostream &o;

    debug() : o(std::cout) {}

    template <class T>
    debug &operator,(T arg)
    {
        std::cout << arg;
        return *this;
    }
    ~debug() { std::cout << '\n'; }
};

// usage:
debug(), "hello", " world",  Variable1, "spliter", variable2;

// Notice: sepcial variable  need to overload `operator <<` for `std::ostream`
// for example
template <class T>
inline std::ostream &operator<<(std::ostream &out, std::optional<T> v)
{
    if (v.has_value()) {
        out << v.value();
    }
    else {
        out << "[None]";
    }
    return out;
}