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 流 冲洗完全。