一、字符串表示与字符串I/o
1、定义字符串
定义字符串的方法有很多,基本的办法是使用字符串常量、char数组、char指针和字符串数组
字符串常量属于静态存储
char数组注意最后一位'\0'
数组与指针的区别
都可以使用数组符号、指针加法,但是只有指针才有增量运算符
</pre><pre name="code" class="plain">char string[] = "abcdefgh";
char * p="abcdefgh";
int i =0;
for(i=0;i<4;i++)
{
putchar(string[i]);
putchar(p[i]);
//putchar(*(string+i));
//putchar(*(p+i));
}
char * word = "Frame";
可以用指针改变这个字符串吗? word[1] = 'U';
编译器可能把相同的字符串作为同一个地址;
建议做法:const char * pl = "Klingons";
2、字符串输入
gets()函数
头文件 stdio.h
原型 char * gets ( char * str );
char name[81];
char * pr;
pr =gets(name);
printf("%s---%s",name,pr);
-------------------------------------------------------------------------
lihao
lihao---lihao
lihao---lihao
如果gets()读取出错或者读到文件尾就会返回NULL
whlie((gets(name)!=NULL)
gets()的不足之处是它不检查预留存储区是否能够容纳实际输入的数据。多出的字符简单的溢出到相邻的内存区。
可以使用fgets().
fgets()函数
头文件: stdio.h
函数原型
char *fgets(char *buf, int bufsize, FILE *stream);
参数
*buf: 字符型指针,指向用来存储所得数据的地址。
bufsize: 整型数据,指明存储数据的大小。
*stream: 文件结构体指针,将要读取的文件流。
返回值
-
成功,则返回第一个参数buf;
-
在读字符时遇到 end-of-file,则eof指示器被设置,如果还没读入任何字符就遇到这种情况,则buf保持原来的内容,返回NULL;
-
如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变。
它的第二个参数来说明最大读入字符数,如果这个参数是n,fgets()就会读取最多n-1个字符或者读完一个换行符为止,由这二者中最先满足的那个来结束输入。
如果fgets()读取到一个换行符,就会把它存到字符串里,而不像gets()那样丢弃。
它还需要第三个参数来说明读哪一个文件。从键盘上读数据时,可以使用stdin作为该参数
char name[81];
char * pr;
fgets(name,81,stdin);
#include<string.h>
#include<stdio.h>
int main ( void )
{
FILE*stream;
charstring[]="Thisisatest";
charmsg[20];
/*openafileforupdate*/
stream=fopen("DUMMY.FIL","w+");
/*writeastringintothefile*/
fwrite(string,strlen(string),1,stream);
/*seektothestartofthefile*/
fseek(stream,0,SEEK_SET);
/*readastringfromthefile*/
fgets(msg,strlen(string)+1,stream);
/*displaythestring*/
printf("%s",msg);
fclose(stream);
return0;
}
scanf()函数
scanf()与gets的主要区别在于它们决定字符串何时结束。
scanf()更基于获取单词而不是获取字符串;
gets()会读取所有字符串,直到遇到第一个换行符为止。
3、字符串输出
puts()函数
头文件: stdio.h
原型:int puts(char *string)
puts()函数用来向标准输出设备(屏幕)写字符串并换行, 其调用格式为: puts(s);
说明:
(1). puts()函数只能输出字符串, 不能输出数值或进行格式变换。
(2). 可以将字符串直接写入puts()函数中。如: puts("Hello, Turbo C2.0");
#include <stdio.h>
#include <stdlib.h>
#define DEF "I am a #defined string."
int main(void) {
char str1[80] = "An array was initialized to me.";
const char * str2 = "A pointer was initialized to me.";
puts("I'm an argument to puts().");
puts(DEF);
puts(str1);
puts(str2);
puts(&str1[5]);
puts(str2 + 4);
return EXIT_SUCCESS;
}
fputs()函数
头文件: stdio.h
原型:int fputs (const char*, FILE*)
向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。成功写入一个字符串后,文件的位置指针会自动后移,函数返回为一个非负整数;否则返回EOF。
fputs()需要二个参数来说明要写的文件。可以使用stdout作为参数来进行输出显示。
与puts()不同,fputs()并不为输出添加自动换行符。
<span style="font-size:18px;">int main(void) {
char str[80] = "I/Osystem.";
FILE * fp;
if ((fp = fopen("strfile", "w")) == NULL)
{
printf("can not open the file.\n");
exit(0);
}
fputs(str, fp);
fclose(fp);
return 0;
}</span>
printf()函数
自动以字符串输入/输出函数
void put1(const char *);
int put2(const char *);
int main(void)
{
put1("If I'd as much money");
put1(" as I could spend,\n");
printf("I count %d characters.\n",
put2("I never would cry old chairs to mend.")); //take care of here
return 0;
}
void put1(const char * string)
{
while (*string) // same as *string != '\0'
putchar(*string++);
}
int put2(const char * string)
{
int count = 0;
while (*string)
{
putchar(*string++);
count++;
}
putchar('\n');
return(count);
}
4、常用字符串函数
#include <string.h>
常用的有strlen()、strcat()、strncat()、strcmp()、strncmp()、strcpy()、sprintf()
和strncpy().
strlen()函数
可以获取字符串的长度。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void fit(char *, unsigned int);
int main(void)
{
char mesg[] = "Things should be as simple as possible,"
" but not simpler.";
puts(mesg);
fit(mesg,23);
puts(mesg);
puts("Let's look at some more of the string.");
puts(mesg + 39);
return 0;
}
void fit(char *string, unsigned int size)
{
if (strlen(string) > size)
*(string + size) = '\0';
}
-------------------------------------------------
Things should be as simple as possible, but not simpler.
Things should be as sim
Let's look at some more of the string.
but not simpler.
Things should be as sim
Let's look at some more of the string.
but not simpler.
strcat()函数
函数接受两个字符串参数。它将第二个字符串的一份拷贝添加到第一个字符串的结尾。
从而使第一个字符串成为一个新的组合字符串,第二个字符串并没有改变。
#define SIZE 80
int main(void)
{
char flower[SIZE];
char addon[] = "s smell like old shoes.";
puts("What is your favorite flower?");
gets(flower);
strcat(flower, addon);
puts(flower);
puts(addon);
return 0;
}
-------------------
What is your favorite flower?
tulip
tulips smell like old shoes.
s smell like old shoes.
tulips smell like old shoes.
s smell like old shoes.
strncat()函数
strcat()函数并不检查第一个数组是否能够容纳第二个字符串。如果没有为第一个数组分配足够大的空间,多出来的字符溢出到相邻存储单元时就会出现问题。
strncat()函数需要另一个参数来指明最多允许添加的字符数目。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 30
#define BUGSIZE 13
int main(void)
{
char flower[SIZE];
char addon[] = "s smell like old shoes.";
char bug[BUGSIZE];
int available;
puts("What is your favorite flower?");
gets(flower);
if ((strlen(addon) + strlen(flower) + 1) <= SIZE)
strcat(flower, addon);
puts(flower);
puts("What is your favorite bug?");
gets(bug);
available = BUGSIZE - strlen(bug) - 1;
printf("length of bug %d\n",strlen(bug));
printf(" length of available %d\n",available);
strncat(bug, addon, available); //have some problem here
puts(bug);
return 0;
}
strcmp()函数
两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止.
特别注意:strcmp(const char *s1,const char * s2)这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。
比较两个字符串内容(不是指针地址)是否相等。如果相等,返回0;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ANSWER "Grant"
#define MAX 40
int main(void)
{
char try[MAX];
puts("Who is buried in Grant's tomb?");
gets(try);
// while (strcmp(try,ANSWER) != 0)
while(strcmp(try,ANSWER))
{
puts("No, that's wrong. Try again.");
gets(try);
}
puts("That's right!");
return 0;
}
strncmp()函数
strcmp()函数比较字符串时,一直比较到找到不同的相应字符,搜索可能要进行到字符串结尾出。
strncmp()函数比较字符串时,可以比较到字符串不同处,也可以比较完全由第三个参数指定的字符数
#include <string.h>
#define LISTSIZE 5
int main(void)
{
char * list[LISTSIZE] = {"astronomy","astounding","astropphysics","ostracize","asterism"};
int count = 0;
int i;
for(i=0;i<LISTSIZE;i++)
{
if(strncmp(list[i],"astro",5) ==0)
{
printf("Found:%s\n",list[i]);
count++;
}
}
printf("Found:%d\n",count);
return 0;
}
----------------------------------
Found:astronomy
Found:astropphysics
Found:2
Found:astropphysics
Found:2
strcpy()函数
原型声明:extern char *strcpy(char* dest, const char *src);
把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针
#define MAX 20
int main(void)
{
char a[MAX]="abc";
char b[MAX]="abcdefghi";
char *p;
p= strcpy(&a[3],b);
puts(a);
puts(b);
puts(p);
return 0;
}
------------------------------------------------------------------------
abcabcdefghi
abcdefghi
abcdefghi
abcdefghi
abcdefghi
int main(void)
{
char a[MAX]="abcdefghijklme";
char b[MAX]="abcdefghi";
char *p;
p= strcpy(&a[3],b);
puts(a);
puts(b);
puts(p);
return 0;
}
------------------------------------------------------------------------
abcabcdefghi
abcdefghi
abcdefghi
abcdefghi
abcdefghi
我们再来看看strcpy()函数的功能:将一个字符串复制到另一个字符串。这个代码无疑是把字符串b复制到a的第4个位置。但是字符串的特性是什么呢?字符串最后一个字节存放的是一个空字符——“\0”,用来表示字符串的结束。把b复制到a之后会令a的空字符把复制后的字符串隔断,所以会显示到abcdefghi就会结束。
strncpy()函数
可能到这里你已经发现了一些问题,如果想把一个字符串的一部分复制到另一个字符串的某个位置,该怎么办呢,显然strcpy()函数是满足不了这个功能的,strncpy()函数是为了弥补strcpy()函数不能检查目标字符串是否容纳下源字符串的不足而设定的一个函数。并且完全可以实现这个功能。
strncpy 是 C语言的库函数之一,来自 C语言标准库,定义于 string.h,char *strncpy(char *dest, char *src, int n),把src所指字符串的前n个字节复制到dest所指的数组中,并返回指向dest的指针。
函数原型char*strncpy(char*dest,char*src,size_tn);
#define MAX 20
int main(void)
{
char a[MAX]="abc";
char b[MAX]="defghihij";
char *p;
p= strncpy(a,b,5);
puts(a);
puts(b);
puts(p);
return 0;
}
---------------------------------------------------------------
defgh
defghihij
defgh
defghihij
defgh
sprintf()函数
原型: int sprintf( char *buffer, const char *format, [ argument] … );
参数列表
#include<stdio.h>
int main()
{
char buffer[50];
int n,a=5,b=3;
n=sprintf(buffer,"%d plus %d is %d",a,b,a+b);
printf("[%s]is a string %d chars long\n",buffer,n);
return 0;
}
--------------------------------------------------------------
[5 plus 3 is 8] is a string 13 chars long