侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 551 篇文章
  • 累计创建 117 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

C++在ACM模式中的输入处理

GabrielxD
2022-11-28 / 0 评论 / 0 点赞 / 49 阅读 / 2,621 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-12-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

输入常用到的方法

std::cin

在标头 <iostream> 定义。

全局对象 std::cin 与标准 C 输入流 stdin 关联。

示例

// 读入整数(跳过中间的所有连续空白符)
int a, b;
cin >> a >> b;

// 读入字符串到c++风格字符串(读到空白符停止)
string s;
cin >> s;

scanf

在标头 <stdio.h> 定义。

stdin 读取数据,按照 format 转译,并将结果存储到指定位置。

用法

int scanf(format, ...);

参数

  • format:指向指定读取输入方式的空终止字符串的指针。
    格式字符串由下列内容组成:

    • 非空白多字节字符,除了 % :每个格式字符串中的这种字符处理来自输入流的准确同一字符,或若它与流的下个字符比较不相等则导致函数失败。

    • 空白符:任何格式字符串中的单个空白符处理所有来自输入的可用连续空白符(如同通过于循环中调用 isspace 确定)。注意格式字符串中 "\n"" " "\t\t" 或其他空白无区别。

    • 转换指示:每个转换指示拥有下列格式:

      • 引入用 % 字符
      • (可选) 赋值抑制字符 ***** 。若存在此选项,则此函数不将结果赋值给任何接收用参数。
      • (可选) 指定最大域宽的整数数字(大于零),即函数进行在当前转换指示所指定的转换时,允许处理的最大字符数。注意若不提供宽度,则 %s%[ 可能导致缓冲区溢出。
      • (可选) 指定接收参数大小的长度修饰符,即实际目标类型。这影响转换准确性和溢出规则。默认目标类型对每个转换类型不同(见下表)。
      • 转换格式指示符

      下列格式指示符可用:

      image-20221128012633128

  • ...:接收用参数

返回值

  • 成功赋值的接收参数的数量(可以为零,在首个接收用参数赋值前匹配失败的情况下),或者若输入在首个接收用参数赋值前发生失败,则为EOF

示例

// 读入整数(跳过中间的所有连续空白符)
int a, b;
scanf("%d%d", &a, &b);

// 读入字符串到c风格字符串(读到空白符停止)
char s[10];
scanf("%s", s);

std::getline

在标头 <string> 定义。

getline 从输入流读取字符并将它们放进字符串。

用法

getline(input, str, delim='\n');

参数

  • input:获取数据来源的流
  • str:放置数据的目标字符串
  • delim:分隔字符

返回值input

示例

// 读取一整行到c++风格字符串
string s;
getline(cin, s);

cin.getline

std::basic_istream<CharT,Traits>::getline

从流释出字符,直至行尾或指定的分隔符 delim

用法

getline(s, count, delim='\n');

参数

  • s:指向要存储字符到的字符串的指针
  • counts 所指向的字符串的大小
  • delim:释出所终止于的分隔字符,释出但不存储它

返回值*this

示例

// 读取一整行到c风格字符串
char s[10];
cin.getline(s, 10);

cin.get

std::basic_istream<CharT,Traits>::get

从流释出字符或多个字符。

用法

int get();

读取一个字符,若可用则返回它。否则,返回 Traits::eof() 并设置 failbiteofbit

返回值

  • 释出的字符或 Traits::eof()

get(ch);

读取一个字符,而若可用则存储于 ch

参数

  • ch:到要写入结果到的字符的引用

返回值

  • *this

get(s, count, delim='\n');

从流中提取字符并将它们作为字符串存储在 s 中,直到提取 n1n-1 个字符或遇到分隔符。分隔符是换行符 '\n'delim(如果指定了此参数),如果找到分隔符,则不会从输入序列中提取,而是保留在那里作为要从流中提取的下一个字符。

参数

  • s:指向要存储结果到的字符串的指针
  • counts 所指向的字符串的大小
  • delim:用以停止释出的分隔字符,不释出且不存储它

返回值

  • *this

get(strbuf, delim='\n');

从流中提取字符并将它们插入到由流缓冲区对象 strbuf 控制的输出序列中,一旦这样的插入失败或在输入序列中遇到分隔符就停止,分隔符是 '\n'delim(如果指定了此参数)。

参数

  • strbuf:要读取内容到的流缓冲
  • delim:用以停止释出的分隔字符,不释出且不存储它

返回值

  • *this

示例

// 读取单字符
char c;
c = cin.get();
cin.get(c);

// 读取c风格字符串
char s[20];
cin.get(s, 10, '.'); // 读取前 9 个字符或直到分隔符 '.'

fgets

在标头 <stdio.h> 定义。

从给定文件流读取最多 count - 1 个字符并将它们存储于 str 所指向的字符数组。若文件尾出现或发现换行符则终止分析,后一情况下 str 将包含一个换行符。若读入字节且无错误发生,则紧随写入到 str 的最后一个字符后写入空字符。

用法

fgets(str, count, stream);

参数

  • str:指向 char 数组元素的指针
  • count:写入的最大字符数(典型的为 str 的长度)
  • stream:读取数据来源的文件流

返回值

成功时为 str ,失败时为空指针。
若遇到文件尾条件导致了失败,则设置 stream 上的文件尾指示器(见 feof() )。这仅若它导致未读取字符才是失败,该情况下返回空指针且不改变 str 所指向数组的内容(即不以空字符覆写首字节)。
若某些其他错误导致了失败,则设置 stream 上的错误指示器(见 ferror() )。 str 所指向的数组内容是不确定的(甚至可以不是空终止)。

示例

// 从c标准输入中读入
char s[1010];
fgets(s, 1000, stdin);

fread

在标头 <stdio.h> 定义。

从给定输入流 stream 读取至多 count 个对象到数组 buffer 中。

用法

fread(buffer, size, count, stream);

参数

  • buffer:指向要读取的数组中首个对象的指针
  • size:每个对象的字节大小
  • count:要读取的对象数
  • stream:读取来源的输入文件流

返回值

成功读取的对象数,若出现错误或读到文件尾,则可能小于 count
sizecount00 ,则 fread 返回 00 且不进行其他动作。
fread 不区别文件尾和错误,而调用者必须用 feofferror 鉴别出现者为何。

示例

// 从c标准输入中读入
char s[1000];
fread(s, 1, 1000, stdin);

常见输入样例

单组输入

输入整数、字符、…

int a, b;
scanf("%d%d", &a, &b);
int a, b;
cin >> a >> b;

输入字符串(空白符分隔)

char s[100];
scanf("%s", s);
string s;
cin >> s;

多组输入

给定数量

int n;
scanf("%d", &n);
while (n--) {
    int a, b;
    scanf("%d%d", &a, &b);
}
int n;
cin >> n;
while (n--) {
    int a, b;
    cin >> a >> b;
}

读到文件尾结束

int a, b;
while (~scanf("%d%d", &a, &b)) {
    // ...
}
int a, b;
while (cin >> a >> b) {
    // ...
}

读到特殊输入结束

输入多组数,两个一组,读入单个 -1 结束:

int a, b;
while (~scanf("%d%d", &a, &b) && a != -1) {
    // ...
}
int a, b;
while (cin >> a >> b && a != -1) {
    // ...
}

整行输入

输入单行到字符串

char s[100];
cin.getline(s, 100);
string s;
getline(cin, s);
char s[100];
fgets(s, 100, stdin);

输入多行直到文件尾结束

vector<string> ss;
string s;

while (getline(cin, s)) {
    ss.push_back(s);
}
char ss[N][N];

int idx = 0;
while (cin.getline(ss[cnt], N)) ++idx;
vector<char*> ss;
char s[N];

while (cin.getline(s, N)) {
    char* tmp = new char[N];
    strcpy(tmp, s);
    ss.push_back(tmp);
}

C++ 标准输入输出提速

太长不看版

int _ = []() {
    ios::sync_with_stdio(false);
    cin.tie(NULL), cout.tie(NULL);
    return 0;
}();

取消 iostream 与 stdio 的同步

C++ 中 的 iostream 为了确保能和 C 中的 stdio 在同一文件操作时按顺序进行,而进行了一些额外的同步操作,这些操作会对性能造成一些影响。
取消同步后,性能可能会得到提升,但之后不应再与 stdio 混用,否则读写顺序上不能保证。

取消同步:

std::ios::sync_with_stdio(false);

解除输入输出流的关联

C++ 中的 输入流 std::cin 默认是关联到 输出流 std::cout 的,任何试图从输入流 读取数据的操作都会先刷新关联的 输出流,这样输出流的缓冲区就会在输入前得到刷新。
关联输入输出流意味着所有输出(包括用户提示等)都会在输入前被打印出来,而不会有在进行输入时之前调用的输出没有得到显示的情况发生。

解除输入输出流的关联来提升性能:

std::cin.tie(NULL);

重新关联:

std::cin.tie(&std::cout);

跳过末尾空白符

cin.ignore(numeric_limits<streamsize>::max(), '\n');

C++ 重定向输入输出

// 将标准输入流重定向到 in.txt 文件
freopen("in.txt", "r", stdin);
// 将标准输出流重定向到 out.txt 文件
freopen("out.txt", "w", stdout); 

参考

0

评论区