scanf and printf

或许关于c语言的各种输入输出的格式的文档网上到处都是,不过我个人觉得不是那么全,最近也在教有心搞acm师弟们开始c语言的输入输出,有些东西还是看看最好,讲的东西容易左耳进右耳出的,YF说到时候会开讲座专门讲这些,不过到时候师弟们真的能吸收多少了,所以敲篇文章好好总结下c语言的输入输出,有不懂的可以留言,或者自己Google。最好的做法就是先Google下,看能不能解决你的问题,不能解决的话再留言都来得及。

1.printf

这是最常见的输出数据的函数,类似cplusplus的cout,先看看printf函数是怎么样的吧

int printf ( const char * format, ... );

Print formatted data to stdout

Writes to the standard output (stdout) a sequence of data formatted as the format argument specifies. After the format parameter, the function expects at least as many additional arguments as specified in format.

这是cplusplus关于printf的解释。


总的来说,printf的七个功能:

  1. 将浮点数值舍入为指定数位的数字
  2. 输出的右对齐和左对齐
  3. 在幂格式来表示浮点数
  4. 用八进制和十六进制表示格式表示无符号整数
  5. 用固定大小的字段宽度和精度来显示所有类型的数据

下面具体讲解之

  1. 输出整数:
  2. 格式符 说明
    d 输出有符号的十进制整数
    i 输出有符号的十进制整数(当和scanf一起使用时,i和d意义是不同的)
    o 显示无符号八进制整数
    u 显示无符号十进制整数
    x or X 显示无符号十六进制整数,X显示大写,x显示小写
    ll 放置在整数格式符之前,以表示是long long整数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    #include<cstdio>
    #define LL long long int
    int main(){
    	printf("%d\n",300);
    	printf("%i\n",300);
    	printf("%d\n",-300);
    	printf("%lld\n",(LL)12345*(LL)1000000);
    	printf("%o\n",300);
    	printf("%u\n",300);
    	printf("%x\n",300);
    	printf("%X\n",300);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    [roowe@roowe-pc ~]$ ./a.out
    300
    300
    -300
    12345000000
    454
    300
    12c
    12C
  3. 输出浮点数:
  4. 格式符 说明
    e or E 以幂记数法的形式输出浮点数值
    f 输出常规的浮点数,默认六位小数,duoble类型(不是lf)和float类型
    g or G 用适当的浮点形式f或者幂形式e来输出浮点数值

    默认情况下,用e,E,f输出的数值,是用精确到小数点右边6位的精度。

    格式符g(或者G)将使用e(或者E)或者使用f来进行格式输出,没有多余的后缀零。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #incude<cstdio>
    int main(){
    	printf("%e\n",123456.789);
    	printf("%e\n",123456.789);
    	printf("%e\n",-123456.789);
    	printf("%E\n",123456.789);
    	printf("%f\n",123456.789);
    	printf("%g\n",123456.789);
    	printf("%G\n",123456.789);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    
    [roowe@roowe-pc ~]$ ./a.out
    1.234568e+05
    1.234568e+05
    -1.234568e+05
    1.234568E+05
    123456.789000
    123457
    123457
  5. 输出字符串和字符:
  6. 格式符 说明
    c 输出字符
    s 输出字符串
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #include<cstdio>
    int main(){
    	char str[5]="ABCD";
    	char ch='I';
    	printf("%c\n",'P');
    	printf("%s\n","LOVE");
    	printf("%c\n",ch);
    	printf("%s\n",str);
    }
    1
    2
    3
    4
    5
    
    [roowe@roowe-pc ~]$ ./a.out
    P
    LOVE
    I
    ABCD
  7. 其他格式:
  8. 格式符 说明
    p 用系统定义的方式来输出指针
    n 存储当前printf语句中已经输出的字符个数,对应的参数是一个整数指针
    % 显示%
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    #include<cstdio>
    int main(){
    	int *ptr;
    	int x=12345;
    	int y;
    	ptr=&x;
    	printf("The value of ptr is %p\n",ptr);
    	printf("The address of x is %p\n\n",&x);
    	printf("Total characters printed on this line:%n",&y);
    	printf("%d\n\n",y);
    	y=printf("This line has 28 characters\n");
    	printf("%d characters were printed\n\n",y);
    	printf("Printing a %% in a format control string\n");
    	return 0;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    [roowe@roowe-pc ~]$ ./a.out
    The value of ptr is 0xbfc01ce8
    The address of x is 0xbfc01ce8
     
    Total characters printed on this line:38
     
    This line has 28 characters
    28 characters were printed
     
    Printing a % in a format control string
  9. 用字段宽度和精度输出
  10. 在百分号和格式符之间插入的整数(这里指的是正整数,若是负数则是左对齐)表示字段宽度,字段宽度大于等于要输出的数据宽度,默认右对齐;字段宽度小于要输出数据宽度,则字段宽度自动增加。负号在字段宽度占一个字符。字段宽度可以和任意格式符一起使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    #include<cstdio>
    int main(){
    	printf("%4d\n",1);
    	printf("%4d\n",12);
    	printf("%4d\n",123);
    	printf("%4d\n",1234);
    	printf("%4d\n",12345);
     
    	printf("%-4d\n",1);
    	printf("%-4d\n",12);
    	printf("%-4d\n",123);
    	printf("%-4d\n",1234);
    	printf("%-4d\n",12345);
     
    	printf("%4d\n",-1);
    	printf("%4d\n",-12);
    	printf("%4d\n",-123);
    	printf("%4d\n",-1234);
    	printf("%4d\n",-12345);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    [roowe@roowe-pc ~]$ ./a.out
       1
      12
     123
    1234
    12345
    1
    12
    123
    1234
    12345
      -1
     -12
    -123
    -1234
    -12345

    printf提供数据精度输出。对于不同数据类型,有不同的意义。

    当和整数格式符一起使用,精度确定的是要输出的最小数位的个数。输出数值的位数小于规定精度,则补前缀0,直到数位和精度相等。

    当和浮点格式符e,f,E一起使用,精度就是小数点后面的数位个数。

    当和格式符g,G一起使用,精度就是输出的有效数字的最多个数。

    当和格式符s一起使用,精度就是从字符串写入的字符的最多个数。

    精度使用方法,在百分号和格式符之间,插入小数点,跟着加入表示精度的整数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    #include<cstdio>
    int main(){
    	int a=873;
    	double f=123.93545;
    	char s[]="Hello World";
     
    	printf("Using precision for integers\n");
    	printf("\t%.4d\n\t%.9d\n\n",a,a);
     
    	printf("Using precision for floating-point numbers\n");
    	printf("\t%.3f\n\t%.3e\n\t%.3g\n\n",f,f,f);
     
    	printf("Using precision for string\n");
    	printf("\t%.8s\n",s);
    	return 0;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    [roowe@roowe-pc ~]$ ./a.out
    Using precision for integers
    	0873
    	000000873
     
    Using precision for floating-point numbers
    	123.935
    	1.239e+02
    	124
    Using precision for string
    	Hello Wo

    可以同时使用字段宽度和精度来输出。

    1
    2
    3
    4
    5
    6
    7
    8
    
    #include<cstdio>
    int main(){
    	int a=9,b=3;
    	printf("%10.3f\n",123.456789);
    	printf("%*.*f\n",9,3,123.456789);//使用参数列表,小数点前面的*代表的是7,后面的代表的是3
    	printf("%*.*f\n",a,b,123.456789);//使用变量名亦可
    	return 0;
    }
    1
    2
    3
    4
    
    [roowe@roowe-pc ~]$ ./a.out
        123.457
        123.457
        123.457
  11. 在printf格式控制字符串中使用标识
  12. 标识 说明
    + 在正数前显示正号,负数前显示负号
    0 用0填充字段
    # 当和八进制o一起使用时,在输出数值前加入0;当和十六进制x或者X一起,在输出数值前加入0x或者0X;当和e,E,f,g,G一起,则强制输出小数点(通常,只有小数点后面有数字才会输出小数点),而且g,G不会去掉多余的后缀0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    #include<cstdio>
    int main(){
    	printf("%d %d\n",678,-678);
    	printf("%+d %+d\n",678,-678);
     
    	int c=1427;
    	double p=1245.600;
     
    	printf("%#o\n",c);
    	printf("%#x\n",c);
    	printf("%#X\n",c);
    	printf("%g\n",p);
    	printf("%#g\n",p);
     
    	printf("%09d\n",c);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    [roowe@roowe-pc ~]$ ./a.out
    678 -678
    +678 -678
    02623
    0x593
    0X593
    1245.6
    1245.60
    000001427
  13. 输出转义字符
  14. 1
    2
    3
    4
    
    #include<cstdio>
    int main(){
    	printf("\'\t\"\?\t\\\t\n");//还有一些请参照课本,or请Google大神,不敲鸟
    }
    1
    2
    
    [roowe@roowe-pc ~]$ ./a.out
    '	"?	\

printf的讲解到此结束,继续scanf咯,哇卡卡。

2.scanf

这是最常用的输入数据的函数,类似cplusplus的cin。现在就各种类型的输入作一下总结。

首先,先明白scanf函数是怎么样的。

1
int scanf( const char * format, ... );

Read formatted data from stdin

Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments. The additional arguments should point to already allocated objects of the type specified by their corresponding format tag within the format string.

这是cplusplus关于scanf函数的解释。

简单的说就是“const char * format“代表输入的格式,”…“代表指向存储输入值的变量的指针,我们在下面称其为“相应的参数”。各种类型格式如下:

输入的格式符 说明
整数
d 读取一个有符号的十进制整数,相应的参数是整数指针
i 读取有符号十进制、八进制或者十六进制的整数,相应的参数是整数指针
o 读取八进制的整数,相应的参数是指向无符号整数的指针
u 读取无符号十进制整数,相应的参数是指向无符号整数的指针
x or X 读取十六进制整数,相应的参数是指向无符号整数的指针
ll or I64 放在所有整数格式符之前,以说明输入的是long long整数或者__int64整数
浮点小数
e,E,f,g,G 读取浮点数值,相应的参数是指向浮点变量的指针
l 放在所有浮点格式符之前,以说明输入的是double型的浮点数
字符和字符串
c 读取一个字符,相应的参数是指向char的指针
s 读取一个字符串,相应的参数是指向char数组的指针,这个数组应该大些,容纳字符串和自动添加的空字符(‘\0′)
扫描集合
[扫描集合] 在字符串中扫描字符集合中的字符
其他
p 当在printf语句中用”%p”输入地址时,用与所产生的格式相同的格式来读取地址
n 存储在这条scanf的输入的字符个数,相应的参数指向整数的指针



现在我给出一些例子

  1. 以下这个是读取整数的例子
  2. 1
    2
    3
    4
    5
    6
    7
    8
    9
    
    #include<cstdio>
    int main(){
    	int a, b, c, d, e, f, g;
    	printf("Enter seven integers: ");
    	scanf("%d%i%i%i%o%u%x", &a,&b,&c,&d,&e,&f,&g);
    	printf("The input displayed as decimal integers is: \n");
    	printf("%d %d %d %d %d %d %d\n",a,b,c,d,e,f,g);
    	return 0;
    }
    1
    2
    3
    
    Enter seven integers: -70 -70 070 0x70 70 70 70
    The input displayed as decimal integers is: 
    -70 -70 56 112  56 70 112
  3. 以下这个是读取浮点数的例子
  4. 1
    2
    3
    4
    5
    6
    7
    
    #include<cstdio>
    int main(){
    	double a,b,c;
    	printf("Enter  three float-point numbers: \n");
    	scanf("%lf%le%lg",&a,&b,&c);
    	printf("%f\n%f\n%f\n",a,b,c);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    
    [roowe@roowe-pc ~]$ ./a.out
    Enter  three float-point numbers: 
    1.23456
    1.23456e+03
    3.3843e-6
    1.234560
    1234.560000
    0.000003
  5. 以下这个是读取字符和字符串的例子
  6. 1
    2
    3
    4
    5
    6
    7
    8
    
    #include<cstdio>
    int main(){
    	char ch;
    	char y[10];
    	printf("Enter a string: ");
    	scanf("%c%s",&ch,y);
    	printf("the character \"%c\"\nthe string is \"%s\"\n",ch,y);
    }
    1
    2
    3
    4
    
    [roowe@roowe-pc ~]$ ./a.out
    Enter a string: hello
    the character "h"
    the string is "ello"
  7. 以下是关于扫描集合来读取字符串的例子
  8. 扫描集合可以扫描输入流中的字符,并查找那些能够匹配扫描集合中所含的字符,每次找到匹配的字符时,将它储存字符数组;遇到扫描集合中的没有的字符,则停止输入字符。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #include<cstdio>
    int main(){
    	char str[9];
    	printf("Enter a string: ");
    	scanf("%[aeiou]",str);//查找aeiou
    	printf("Input was %s\n",str);
    	printf("Enter a string: ");
    	scanf("%[^aeiou]",str);//查找不是aeiou
    	printf("Input was %s\n",str);
     
    }
    1
    2
    3
    4
    5
    6
    
    [roowe@roowe-pc ~]$ ./a.out
    Enter a string: ouiaedjf
    Input was ouiae
    Enter a string: sjhykoia
    Input was djf
    sjhyk
  9. 以下是使用字宽来读取数据
  10. 1
    2
    3
    4
    5
    6
    7
    8
    
    #include<cstdio>
    int main(){
    	int x,y;
    	printf("Enter a six digit number: ");
    	scanf("%2d%d",&x,&y);
    	printf("The integers input were %d and %d\n",x,y);
    	return 0;
    }
    1
    2
    3
    
    [roowe@roowe-pc ~]$ ./a.out
    Enter a six digit number: 123456
    The integers input were 12 and 3456
  11. 跳过特殊字符读取数据
  12. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    #include<cstdio>
    int main(){
    	int year,day,month;
    	printf("Enter a date in the form mm-dd-yyyy: ");
    	scanf("%d%*c%d%*c%d",&month,&day,&year);
    	printf("month=%d day=%d year=%d\n",month,day,year);
    	printf("Enter a date in the form mm/dd/yyyy: ");
    	scanf("%d%*c%d%*c%d",&month,&day,&year);
    	printf("month=%d day=%d year=%d\n",month,day,year);
    }
    1
    2
    3
    4
    5
    
    [roowe@roowe-pc ~]$ ./a.out
    Enter a date in the form mm-dd-yyyy: 3-12-2010
    month=3 day=12 year=2010
    Enter a date in the form mm/dd/yyyy: 5/6/2012
    month=5 day=6 year=2012
  13. 关于long long型的整数问题
  14. long long int 和__int64起到的是一样效果,用来表示64位整数(这里指的是二进制),不过在不同的平台的用的是不同的,在linux的GNU下,用long long int,在MS-windows下VC(或者VS)用__int64,格式分别是”lld” and “I64d”,这里郑重说明下,如果你对自己的编译环境不熟悉的话,可以做一下A+B

弄了两天,终于完成了,希望对acm新手有帮助吧,如果觉得不错的话,做一下评论以资鼓励;如果觉得哪里有问题的话,留言说明下。那些不搞acm的,你们或许不需要懂格式种种渣,所以看到此文请勿吐槽。

显然这些不是我随便YY出来的,参考了一些书籍的代码和讲解,还有网上的资料,之后才整合出来的。

还有一些其他的读取数据,输出数据的函数,可以到cplusplus查查,例如gets,getchar,puts,putchar等等。

17 篇回應 (訪客:11 篇, 博主:6 篇)

  1. David ~

    果断顶起来!!!

  2. stjzcm ~

    牛逼,果断顶起!

  3. CH4 ~

    很好很强大。。。orz。。。

  4. Arios ~

    非常给力!

  5. MiYu ~

    :as21 小萝莉空间好热闹……. 我那都没人 :as32 :as32

  6. Jeflie ~

    一年了,第一次来,看到一篇不可多得的好文章,有点可惜的是当初没来这学习输入输出。此外,我在你Q上留了言,是关于最近这次月赛的,也不是什么大问题,有空再慢慢看。

    • Roowe ~

      話說我暫時還沒有收到任何關於消息哦(或者web qq和手機qq漏了,所以儘量郵件),可以的話,你發下郵件到我的Gmail,解題報告有聯繫方式!

留下評論

:?: :razz: :sad: :!: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: :smile: :evil:
貼圖 表情 ( ps. 若要貼代碼, 請將 "<" 改成 "&lt;" 即可, 此方法在所有 WP 網站均適用. )

這篇文章上的評論 RSS feed TrackBack URL