C字符串/输入输出操作 辨析

  
1.       字符串
内部表示:字符串用字符数组表示,任何时候,字符串在内存中被分配为连续的字节。用 ’/0’表示该字符的结束。
应此,字符串可用数组和字符指针两种表示方式。
处理字符串的每个字符,常用下面结构:
 for( i=0 ; str[i] != ‘/0’ ; i++)
{
   processing
}
 
或者:
 for( cp= str ; *cp != ‘/)0’ ;cp++)
{
 processing
}
2.       数据类型 string
ANSI 本身没有定义 string 类型 ; 它只给出了<string.h>库,为用户提供关于字符串的一些处理操作。实际上这个接口并没有将底层数据结构和用户很好的隔离起来。使用该库的用户,需要了解底层的数据表示。如 在复制操作中 ,用户需要了解src的字符串长度,并且为dst分配更大一点的空间,以避免over flow。更值得注意的是,string 库把 分配内存的任务交给了用户,用户需要为整个字符串的存储负责。
标准c中常常使用 char * 来表示字符串;
   实际上在很多非标准的字符串处理函数中,往往将字符串抽象出来,定义如下类型:
 typedef char * string ;
 这样就能从整体意义上看待字符串。
3.       ANSI <string.h> 中的一些重要基本函数
      char *strcpy ( char * s1,const char *s2) ;
     char *strcat(char *s1 , const char *s2) ;
     int strcmp(const char *s1,const char *s2) ;
     char *strchr( const char *s1 , int c );
     char *strstr(const char *s1 , const char *s2) ;
     size_t strlen(const char *s);
 
4.       标准的 I/O
ANSI在接口<stdio.h>中定义了标准的 I/O库,它方便了其它函数读写文件。
文件
c语言中将文件分为数据文件和标准文件。对于一般数据文件,访问时,需要申明文件指针变量,即 FILE* ,如:
FILE *infile , *outfile ;
至于标准文件,I/O库定义了3个特殊的标识符,分别是stdin(标准输入文件,通常可视为用户的键盘输入) , stdout(标准输出文件,通常可视为终端,如显示屏) ,stderr(标准错误文件,);它们都是FILE* 的常量指针。
这些概念似乎和UNIX系统有莫大的渊源,在UNIX/LINUX中有相同的定义。
几种不同的 I/O
First--- 字符 I/O
即单个字符的对文件进行处理,比较常用的函数有:
int getc(FILE *infile) ;
int fgetc(FILE *infle);
int getchar(); 相当于 getc(stdin);
 
int putc(char ch , FILE *outfile) ;
int fputc(char ch , FILE *outfile) ;
int putchar( int ch) ;
Second--- 面向行的 I/O
即对文件进行逐行处理:
char *fgets ( char *s , int n , FILE *infile );
需要注意的是,当遇到换行符或是已经传输了 n – 1个字符,或者到达文件尾时函数停止继续读取,并在结尾加一个空字符‘/0’并返回。应此实际上一次调用最多只能传输
n – 1个字符。
 char *gets(char *s) ;
该函数从stdout流中读取字符串,丢弃遇到的换行符,在尾部加入 ‘/0’;
 
实际上,应该尽量避免使用gets()函数,因为它对传输字符的个数没有限制,可能会产生溢出自己的传输缓冲区的问题。尽量使用fgets()函数来代替。
 
相对的有:
void fputs( char *s , FILE *outfile ) ;
 
Third---- 格式化的 I/O
与许用户指定格式进行操作:
int printf (const char *format , . . . ) ;
int sprintf (char *s , const char *format , . . . ) ;
int fprintf (FILE *stream , const char * format , ….) ;
 
int scanf (const char *format , . . .) ;
int fscanf (FILE *stream , const char *format , . . .) ;
int sscanf( char * s , const chart *format , . . .) ;
 
通常对于scanf()相关的操作容易出现问题:
如:
 
用scanf(“%s”,string);期望获取字符串时,但实际上,当用户输入”This is a test ”时, string 只存储了”This” ;这是因为 scanf 操作在遇到空白字符(如 空格,制表符,换行符等)时,scanf会忽略剩余的字符.
通常解决的办法有以下:
第一种: 放弃scanf , 选用 fgets() 或者 gets() 来读取;
第二种: 改变控制方式, 如使用 scanf(“%[… ]”,string);它使得scanf直到第一次读取到不在方框中的字符串时停止 ; 如 scanf(“%[A-Z]”,string); 只读取A-Z的字符;
     对于解决获取字符串的问题: 使用 scanf( “ %[ ^ /n]”,string) ;它指明scanf直到读取”/n”时停止;[ ^ …]表示读取不是相应字符(串)的字符串。
 
另外一个问题是:如果先前已经用scanf读取了一次,此后,stdin中会有 ‘/n’ 标记字符,该字符会被下一次的读取操作时取走,从而导致编程时各种各样的问题 ;最保险的做法是 在使用scanf等时 再使用 fflush( stdin);将stdin 流 冲洗完全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值