1: scanf(), sscanf(), fscanf() 三姐妹
这是c语言的"输入三姐妹",她们定义在<stdio.h>中,分别掌管从标准输入读,从字符串读,和从文件读的功能。具体点说,她们是从一个数据源,根据一个格式字符串,读取数据并存入指定的变量中,返回类型是读入的变量的数量。
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d-%d\n",a,b);
char s[10] = "123 456";
sscanf(s,"%d%d",&a,&b);
printf("%d-%d\n",a,b);
FILE * f = fopen("in.txt","r");
fscanf(f,"%d%d",&a,&b);
printf("%d-%d\n",a,b);
return 0;
}
---效果---
1 2
1-2
123-456
123-456
2: printf(), sprintf(), fprintf() 三兄弟
这是c语言的"输出三兄弟",他们定义在<stdio.h>中,分别掌管写到标准输出,写到字符串,和写到文件的功能。具体点说,他们都遵循一个核心模式:根据一个格式字符串,将数据格式化,并输出到一个指定的目的地。
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int a = 1, b = 2;
printf("%d-%d\n",a,b);
char buf[10];
sprintf(buf,"%d-%d",a,b);
puts(buf); // 会自动换行
FILE * f = fopen("out.txt","w");
fprintf(f,"%d-%d",a,b);
return 0;
}
3: 输入输出重定向
可以利用输入输出重定向配合条件编译实现将数据读取到文件里面,加快差错纠正效率。
#define LOCAL
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
return 0;
}
4: 使用fgets()而不是gets()
由于gets()函数存在严重的缓冲区漏洞,所以不建议使用,我们可以用fgets(s,maxn,stdin);来替代gets(), 效果是一样的。不过要注意,该函数是读取一行,遇到换行自动停止并处理掉换行符。
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
char s[20];
fgets(s,10,stdin);
puts(s);
return 0;
}
---效果---
1 2 3 4 5
1 2 3 4 5
5: getline() + stringstream 实现从一个长度不定字符串里面读取变量值
如果题目给出的输入是一行长度不定字符串,有空格,我们就可以用该方式把里面的变量值读取出来。这里注意要添加一个头文件,且该方法比较"慢"。
#include<iostream>
#include<string>
#include<cstdio>
#include<sstream>
using namespace std;
int main()
{
int n; scanf("%d\n",&n); // 这里scanf加个'\n'是为了让getline()不要直接把'\n'读了导致空串。
string s;
getline(cin,s);
stringstream ss(s);
int x;
while(ss >> x) cout << x << '\n';
return 0;
}
---效果---
123 23 4 6 67 67 7689 99 100
123
23
4
6
67
67
7689
99
100
6: 输入输出重载
通过运算符重载,可以让我们自己定义的数据类型像基本数据类型一样输入输出。
#include <iostream>
#include <iomanip> // 用于 std::fixed, std::setprecision
class Point {
private:
double x, y;
public:
Point(double x_val = 0.0, double y_val = 0.0) : x(x_val), y(y_val) {}
// 声明友元函数来访问私有成员 x, y
friend std::ostream& operator<<(std::ostream& os, const Point& pt);
friend std::istream& operator>>(std::istream& is, Point& pt);
};
// 输出重载实现
std::ostream& operator<<(std::ostream& os, const Point& pt) {
// 使用 iomanip 控制输出格式,例如保留两位小数
os << std::fixed << std::setprecision(2);
os << "Point(" << pt.x << ", " << pt.y << ")";
return os;
}
// 输入重载实现
std::istream& operator>>(std::istream& is, Point& pt) {
// 假设输入格式为 (x, y)
char ch1, ch2, ch3;
double temp_x, temp_y;
// 尝试匹配格式 "(x, y)"
is >> ch1 >> temp_x >> ch2 >> temp_y >> ch3;
// 检查格式是否正确
if (ch1 == '(' && ch2 == ',' && ch3 == ')') {
pt.x = temp_x;
pt.y = temp_y;
} else {
// 如果格式不匹配,设置流状态为 fail
is.setstate(std::ios::failbit);
}
return is;
}
int main() {
Point p1(3.14159, 2.71828);
std::cout << "Initial point: " << p1 << std::endl;
Point p2;
std::cout << "Enter a point in format (x, y): ";
std::cin >> p2;
if (std::cin) {
std::cout << "You entered: " << p2 << std::endl;
} else {
std::cout << "Invalid format! Please use (x, y)." << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
return 0;
}