关于PAT(Programming Ability Test)编辑器不支持C语言gets函数的替代方案
你可能会好奇PAT的编辑器为什么不支持C语言的gets函数,来获取整行字符串的输入?总的来说,gets函数不安全,怎么不安全,请自行搜索。。。
下面给出两种替代方案,分别是C语言函数fgets()函数和C++语言的getline()函数。
替代方案一:使用C语言函数fgets()函数
我们首先看一下这个函数的用法,下图是截自官方文档(不是很清楚,有兴趣可以自行搜索)。
fgets
Defined in header <stdio.h>
char *fgets( char *str, int count, FILE *stream );
(until C99)
char *fgets( char *restrict str, int count, FILE *restrict stream );
解释:从指定的流中读取至多count - 1个字符,并将这些字符存储在str指向的字符数组中。在解析过程中,如果碰到了换行符(在包含换行符的str中)或者文件结束符,解析就会停止。如果str中读取了字符并且没有错误发生,那么就立即在str的最后一个非空字符的后面追加一个’\0’。
参数
- str:字符数组指针;
- count:要写字符个数的最大值(Usually,是str的长度)
- stream:可以读取数据的文件流
其它的不解释了,目前用不到。
下面给出一个案例,以PAT官网的题号1021为例(代码主要参考胡凡的算法笔记)。
#include <cstdio>
#include <cstring>
using namespace std;
int main() {
char str[1010];
int ans[10] = {0};
fgets(str, sizeof(str), stdin);
int len = strlen(str);
for (int i = 0; i < len; i++) {
ans[str[i] - '0']++;
}
for (int i = 0; i < 10; i++) {
if (ans[i] != 0)
printf("%d:%d\n", i, ans[i]);
}
return 0;
}
替代方案二:使用C++语言的getline()函数
解释:getline从输入流中读取字符至一个字符串(string类型)中:
- Behaves as UnformattedInputFunction, except that input.gcount() is not affected(不太懂,不翻译了).在构造和检查哨兵(sentry)对象后,其行为如下:
- 调用str.ease();
- 从输入中提取字符并把他们追加到str中,指导以下情况中的一个发生(以下列次序检查):
a) 文件结束符:end-of-file condition on input, in which case, getline sets eofbit.
b) 用户指定的界定符(界定符并不会追加到str末尾):the next available input character is delim, as tested by Traits::eq(c, delim), in which case the delimiter character is extracted from input, but is not appended to str.
c) str.max_size() characters have been stored, in which case getline sets failbit and returns. - If no characters were extracted for whatever reason (not even the discarded delimiter), getline sets failbit and returns.
- Same as getline(input, str, input.widen(’\n’)), that is, the default delimiter is the endline character.(默认的界定符是endline)
Parameters
input:获取数据的输入流
str:读取的字符被存放的地方
delim:界定符(碰到界定符,getline函数就读取结束了)
例子:
#include <iostream>
#include <string>
int main()
{
std::string name;
std::cout << "Please, enter your full name: ";
std::getline(std::cin, name);
std::cout << "Hello, " << name << "!\n";
return 0;
}
}
(翻译文档真不容易,劝退啊…)