OI 常用的输入方法和技巧

cin

cin 可能是最简单的输入方式,但相比于 scanfcin 的速度更慢(关闭同步后会变快)。

cin 可以输入多种类型的数据并且不必写出输入的每个数据的具体类型(不像 scanf),但是在读入一些特殊的类型(如特殊格式、指定的文本)方面不易操作。

cin 读到文件尾则会返回 -1(也就是 EOF)。


scanf

scanf 是 C 中的输入方式,但是速度比 cin 快不少。使用 scanf 时注意要在双引号中选择正确的格式说明符,读入的数据要用 & 取地址。

注意:scanf 不能读取 string 类型的变量。

格式说明符

在 OI 中,常用的格式说明符如下:

  • %d:读入 int 型整数;
  • %lld:读入 long long 型整数;
  • %a:读入 float 型;
  • %la:读入 double 型;
  • %lla:读入 long double 型;
  • %c:读入一个字符;
  • %s:读入一个字符串;

(对于 %a%la%lla,其中的 a 可以改为 efg。)

%c 只能读入一个字符,而 %s 读入的是字符数组。使用了错误的说明符会导致程序运行错误。

返回值与不定长输入

cin 一样,scanf 会返回成功读取的数据个数,读到文件尾则会返回 -1(也就是 EOF)。

对于一些输入数据个数不确定的题目(比如著名的导弹拦截),我们可以利用这点输入数据。参考代码:

int n=0,a[2005];
while(scanf("%d",&a[++n])!=EOF);
n--;

(读入到 EOF 时仍然执行了 ++n,因此需要 n--。)

输入固定格式的数据

在输入一些数据时有固定格式,例如在输入时间时有 hh:mm,为了防止在输入时将冒号作为数据的一部分读取,我们可以在 scanf 中两个格式说明符之间加上 :,即为 scanf("%d:%d",&h,&m)注意,这需要保证读入的数据满足这个格式。

示例:读入格式为 [编号]年/月/日 - 时:分:秒 的数据:

int n,y,m,d,hh,mm,ss;
scanf("[%d]%d/%d/%d - %d:%d:%d",&n,&y,&m,&d,&hh,&mm,&ss);

getchar

getchar 会返回读取到的一个字符,以此写成的快读(可能)比前两者更快,且更易于扩展。与前两者一样,读到文件尾时 getchar 会返回 EOF

注意:getchar 返回一个字符。若这个字符为数字,其 ASCII 码比其代表的数字多 48。

快读

最简单的快读的基本原理便是逐个读入字符直到数字,再逐个读入数字直到结束。代码实现如下:

int read(){
    int w=0,f=1;//w 为数,f 为符号
    char ch=getchar();
    while(ch<'0'||ch>'9'){//读取数字之前的字符
        if(ch=='-')f=-1;//如果是负号则 f=-1
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){//读取数字
        w=w*10+ch-48;//ASCII 码减去 48 才是真正的数字
        ch=getchar();
    }
    return w*f;
}

读入指定字符

使用类似的方法,我们可以只读取指定的字符,忽略其他字符。

例一:读取 01 串,直至下一个其他字符:

int n=0;
bool a[105];
char ch=getchar();
while(ch!='0'&&ch!='1')ch=getchar();//读取串之前的其他字符
while(ch=='0'||ch=='1'){//读取 01 串
    a[++n]=ch;
    ch=getchar();
}

例二:读取一段话并统计其中出现的空格数量,直至文件尾。

int cnt=0;
char ch=getchar();
while(ch!=EOF){
    if(ch==' ')cnt++;
    ch=getchar();
}

后记

  1. 使用 getchar 快读不一定比关闭了同步的 cin 快,因此更常用的方法是使用 fread 写快读,在此不过多讲述。

  2. 从控制台读取时,需要按下 Ctrl+Z 输入文件尾。从文件读取或是在 OJ 上测评则不会有此问题。

  3. 参考资料:

    std::scanf, std::fscanf, std::sscanf - cppreference.com

posted @ 2022-04-30 18:20  ofbwyx  阅读(490)  评论(0编辑  收藏  举报