c输入输出


格式输出:

printf(格式控制, 输出表列);
%d 十进制数  %md m为指定的宽度 若数据位数小于m,则左端补以空格;若大于m,则按实际位数输出
%ld 长整型数据  %mld 指定字段宽度
%o 八进制整数形式  %mo
%x 十六进制整数形式  %mx
%u unsigned型数据,它也可用%o或%x格式输出
%c 一个字符   %mc
%s 字符串 有几种用法
 1.%s
   printf("%s", "China");
   输出 China
 2.%ms 控制为m列 若串长小于m, 则左补空格,大于则突破m限制,将字符串完全输出
 3.%-ms 若串长小于m, 则右补空格(居左)
 4.%m.ns 输出占m列,取字符串左端n个字符.这n个字符输出在m列的右侧,左补空格
 5.%-m.ns m.n同上,这n个字符输出在m列的左侧,右补空格.若n>m,则m自动取n值,保证n个字符正常输出
%f 输出实数(包括单.双精度),以小数形式输出
 1.%f 输出全部整数部分,输出6位小数
 2.%m.nf 指定输出的数据共占m列,其中有n位小数.若数值长度小于m,则左端补空格
 3.%-m.nf 指定输出的数据共占m列,其中有n位小数.若数值长度小于m,则右端补空格
%e 以指数形式输出实数
 1.%e 不指定输出数据所占的宽度和数字部分的小数数位,数值按规范化输出
 2.%m.ne 和 %-m.ne 输出占m列,n指输出的数据的小数部分(尾数)的小数数位,-同上
%g 输出实数,根据数值大小,自动选择f格式或者e格式(选择输出宽度小的),且不输出无意义的零
格式控制中可以包含转义字符,如'/n' '/t' '/b' '/r'
输出%的方法 printf("%f%%", 1.0/3) 输出: 0.333333%


格式输入

scanf(格式控制, 地址表列) sscanf
类似printf .以例程解释
1. scanf("%3d%3d", &a, &b); //列数截取数据
   input -> 123456
   then -> a = 123  b = 456
2. scanf("%2d %*3d %2d", &a, &b) //*表示跳过列数读取数据
   input -> 12 345 67
   then -> a = 12 b = 67
3. scanf("%d, %d", &a, &b)
   input -> 1, 4  //在格式控制中,如果有非格式说明外的字符,应该在输入时在对应位置输入该字符
   scanf("%d   %d", &a, &b)  //输入时,两数据应有不少于格式控制中的空格
   scanf("%c%c%c", &a, &b, &c)  //用%c输入字符时,空格字符和转义字符都作为有效字符输入
4. %s 输入字符串.将字符串传送到一个字符数组中,输入时以非空白字符开始,以第一个空白字符结束.
     字符串以串结束标志'/0'作为最后一个字符
5. * 符用以表示该输入项读入后不赋予相应的变量,即跳过该输入值。
   scanf("%d %*d %d",&a,&b);  //当输入为:1 2 3 时,把1赋予a,2被跳过,3赋予b。
6. 在输入数据时,遇以下情况时认为该数据结束
   (1)遇空格 或 回车 或 跳格(tab)
   (2)按指定的宽度结束. 如3列的%3d
   (3)非法输入
7. 输入带空格的字符串
    scanf("%[^/n]%*c", str);
    对比如下
    #include <stdio.h>
    #include <string.h>
    int main()
    {
        char str[222];
        char c;
        scanf("%[^/n]", str);
        printf("%s", str);
        scanf("%c", &c);
        printf("%c", c);
        return 0;
    }
8. 函数 int sscanf (const char *str,const char * format,........);
sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。转换后的结果存于对应的参数内。
sscanf与scanf类似,都是用于输入的,只是scanf以stdin为输入源,前者以固定字符串为输入源。
    # include < stdio. h>
    int main( )
    {
          const char * s = "iios/12DDWDFF@122" ;
          char buf[ 20] ;

          sscanf ( s, "%*[^/]/%[^@]" , buf ) ;
          printf ( "%s/n" , buf ) ;

          return 0;
    }
    结果为: 12DDWDFF
9. scanf 和 sscanf 的一些特殊用法:(类似正则)
    %[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
    %[aB'] 匹配a、B、'中一员,贪婪性
    %[^a] 匹配非a的任意字符,贪婪性
        1. 常见用法。
          charstr[ 512] = { 0} ;
          sscanf( "123456" , "%s" , str) ;
          printf( "str=%s" , str) ;
        2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
          sscanf( "123456" , "%4s" , str) ;
          printf( "str=%s" , str) ;
        3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
          sscanf( "123456abcdedf" , "%[^]" , str) ;
          printf( "str=%s" , str) ;
        4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
          sscanf( "123456abcdedfBCDEF" , "%[1-9a-z]" , str) ;
          printf( "str=%s" , str) ;
        5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
          sscanf( "123456abcdedfBCDEF" , "%[^A-Z]" , str) ;
          printf( "str=%s" , str) ;
    % [ ] 的用法:
    % [ ] 表示要读入一个字符集合, 如果[ 后面第一个字符是”^”,则表示反意思。
        [ ] 内的字符串可以是1或更多字符组成。空字符集(% [ ] )是违反规定的,可导致不可预知的结果。% [ ^ ] 也是违反规定的。
    % [a-z]
        读取在 a-z 之间的字符串,如果不在此之前则停止,如
        char s[ ] = "hello, my friend” ; // 注意: ,逗号在不 a-z之间
        sscanf( s, “%[a-z]”, string ) ; // string=hello
    %[^a-z]
        读取不在 a-z 之间的字符串,如果碰到a-z之间的字符则停止,如
        char s[]=" HELLOkitty” ; // 注意: ,逗号在不 a-z之间
        sscanf ( s, “% [ ^ a- z] ”, string ) ; // string=HELLO
    %*[^=]
        前面带 * 号表示不保存变量。跳过符合条件的字符串。
        char s[ ] = "notepad=1.0.0.1001" ;
        char szfilename [ 32] = "" ;
        int i = sscanf ( s, "%*[^=]" , szfilename ) ;
        // szfilename=NULL,因为没保存
        int i = sscanf ( s, "%*[^=]=%s" , szfilename ) ;
        // szfilename=1.0.0.1001
    %40c 读取40个字符
    %[^=]
        读取字符串直到碰到’= ’号,’^’后面可以带更多字符, 如:
         char s[ ] = "notepad=1.0.0.1001" ;
        char szfilename [ 32] = "" ;
        int i = sscanf ( s, "%[^=]" , szfilename ) ;
        // szfilename=notepad


字符串处理函数

1.puts(字符数组)
   将一个字符串输出到终端
   char str[] = {"Hello otto./n"};
   puts(str);
2.gets(字符数组)   warning: the `gets' function is dangerous and should not be used.
   从终端输入一个字符串到字符数组,并且返回字符数组的起始地址
   gets(str);
3.strcat(字符数组1,字符数组2)
   把字符串2连接到字符串1后面,结果放在字符数组1中,并返回字符数组1的地址.
   a)字符数组1必须足够大,以容纳连接后的新字符串.
   b)连接时将字符串1后的'/n'取消,保留字符串2的'/n'
4.strcpy(字符数组1,字符数组2)
   将字符串2复制到字符数组1中去.
   a)字符数组1必须足够大,以容纳连接后的新字符串.
   b)字符数组1必须写成数组名形式,字符数组2还可以是一个字符串常量
   c)复制时连同字符串后的'/n'一起复制到字符数组1中去
   d)不能用赋值语句将一个字符串常量或字符数组直接给一个字符数组
   e)可以用strncpy函数将字符串2中前面n个字符赋值到字符数组1中
        strncpy(str1, str2, n);  n不应大于str1的长度
5.strcmp(字符串1, 字符串2)
   对两个字符串自左至右逐个字符相比(ASCII码,按英文字典顺序,在后面的为"大",小写字母比大写"大")
   返回比较结果:
     a)如果字符串1=字符串2,则函数值为0
     b)如果字符串1>字符串2,则函数值为一个正整数
     c)如果字符串1<字符串2,则函数值为一个负整数
6.strlen(字符数组)
   返回字符串的实际长度(不包括'/n')
7.strlwr(字符串)
   将字符串中大写字母换成小写字母
8.strupr(字符串)
   将字符串中小写字母换成大写字母


字符串的输入输出与空间分配:

char p[34] = "string";
gets(p);  //可以输入
char *aa;
//gets(aa);  //不可以输入
aa = (char*)malloc(30);
gets(aa);  //可以输入  分配空间


getch()    getche()    getchar()

getche()  有返回显示 //getch() with e(echo) 回显

    getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,把该字符显示在屏幕上
    getch()和getche()是conio.h中的库函数,从键盘接收字符。   
    区别在于: getchar()函数等待输入直到按回车才结束(前提是缓冲区没有数据),回车前的所有输入字符都会逐个显示在屏幕上。但只有第一个字符作为函数的返回值。getch()每次都等待用户的输入,因为getch()从键盘接收,即时的接收,并不是从stdin流中去读取数据。

    getchar()从stdin流中读取字符,所以第一个getchar()接受的是刚刚中断的流队列中即将出列的第一个字符(不限于回车符),如果流队列不为空,执行getchar()就继续直到把回车符也放空为止,空了之后再在执行getchar()就停下等待你的输入了。
    getchar有一个int型的返回值.当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符也放在缓冲区中).getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕.如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取.也就是说, 后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完为后,才等待用户按键.
  getch与 getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回,getch返回值是用户输入的ASCII码,出错返回-1.输入的字符不会回显在屏幕上.getch函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用 getch函数暂停程序运行,当按任意键后程序继续运行.


 c与正则表达式
  标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库,许多Linux发行版本都带有这个函数库。
  编译正则表达式
  为了提高效率,在将一个字符串与正则表达式进行比较之前,首先要用regcomp()函数对它进行编译,将其转化为regex_t结构:
int regcomp(regex_t *preg, const char *regex,int cflags);
  参数regex是一个字符串,它代表将要被编译的正则表达式;参数preg指向一个声明为regex_t的数据结构,用来保存编译结果;参数cflags决定了正则表达式该如何被处理的细节。
  如果函数regcomp()执行成功,并且编译结果被正确填充到preg中后,函数将返回0,任何其它的返回结果都代表有某种错误产生。
  匹配正则表达式
  一旦用regcomp()函数成功地编译了正则表达式,接下来就可以调用regexec()函数完成模式匹配:
  int regexec(const regex_t *preg,
  const char *string, size_t nmatch,
  regmatch_t pmatch[], int eflags);
  typedef struct {
  regoff_t rm_so;
  regoff_t rm_eo;
  } regmatch_t;
  参数preg指向编译后的正则表达式,参数string是将要进行匹配的字符串,而参数nmatch和pmatch则用于把匹配结果返回给调用程序,最后一个参数eflags决定了匹配的细节。
  在调用函数regexec()进行模式匹配的过程中,可能在字符串string中会有多处与给定的正则表达式相匹配,参数pmatch就是用来保存这些匹配位置的,而参数nmatch则告诉函数regexec()最多可以把多少个匹配结果填充到pmatch数组中。当regexec()函数成功返回时,从string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一个匹配的字符串,而从 string+pmatch[1].rm_so到string+pmatch[1].rm_eo,则是第二个匹配的字符串,依此类推。
  释放正则表达式

  无论什么时候,当不再需要已经编译过的正则表达式时,都应该调用函数regfree()将其释放,以免产生内存泄漏。
void regfree(regex_t *preg);
  函数regfree()不会返回任何结果,它仅接收一个指向regex_t数据类型的指针,这是之前调用regcomp()函数所得到的编译结果。
  如果在程序中针对同一个regex_t结构调用了多次regcomp()函数,POSIX标准并没有规定是否每次都必须调用regfree()函数进行释放,但建议每次调用regcomp()函数对正则表达式进行编译后都调用一次regfree()函数,以尽早释放占用的存储空间。
  报告错误信息
  如果调用函数regcomp()或regexec()得到的是一个非0的返回值,则表明在对正则表达式的处理过程中出现了某种错误,此时可以通过调用函数regerror()得到详细的错误信息。
  size_t regerror(int errcode,const regex_t *preg, char *errbuf,size_t errbuf_size);
  参数errcode是来自函数regcomp()或regexec()的错误代码,而参数preg则是由函数regcomp()得到的编译结果,其目的是把格式化消息所必须的上下文提供给regerror()函数。在执行函数regerror()时,将按照参数errbuf_size指明的最大字节数,在errbuf缓冲区中填入格式化后的错误信息,同时返回错误信息的长度。
  应用正则表达式
  最后给出一个具体的实例,介绍如何在C语言程序中处理正则表达式。
上述程序负责从命令行获取正则表达式,然后将其运用于从标准输入得到的每行数据,并打印出匹配结果。执行下面的命令可以编译并执行该程序:
# gcc regexp.c -o regexp
# ./regexp 'regex[a-z]*' < regexp.c
0003: #include <regex.h>
$0='regex'
0027: regex_t reg;
$0='regex'
0054: z = regexec(?, lbuf, nmatch, pm, 0);
$0='regexec'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值