C学习笔记(七)字符串与字符串函数

一、字符串表示与字符串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

如果gets()读取出错或者读到文件尾就会返回NULL
whlie((gets(name)!=NULL)
gets()的不足之处是它不检查预留存储区是否能够容纳实际输入的数据。多出的字符简单的溢出到相邻的内存区。
可以使用fgets().


fgets()函数

头文件: stdio.h

函数原型

char *fgets(char *buf, int bufsize, FILE *stream);

参数

*buf: 字符型指针,指向用来存储所得数据的地址。
bufsize: 整型数据,指明存储数据的大小。
*stream: 文件结构体指针,将要读取的文件流。

返回值

  1. 成功,则返回第一个参数buf;
  2. 在读字符时遇到 end-of-file,则eof指示器被设置,如果还没读入任何字符就遇到这种情况,则buf保持原来的内容,返回NULL;
  3. 如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变。
从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。

它的第二个参数来说明最大读入字符数,如果这个参数是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);
puts(s) 等效于 printf ("%s\n",s),前提 :s是C风格字符串,最后以'\0'结尾。
说明:
(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.




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.




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



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


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


我们再来看看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


sprintf()函数

把格式化的数据写入某个字符串缓冲区

原型:  int sprintf( char *buffer, const char *format, [ argument] … );
参数列表
bufferchar型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument].. .:可选参数,可以是任何类型的数据。
返回值:字符串长度( strlen

#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






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python学习笔记|字符串与正则表达式练习题答案 1. 练习题1: 题目:给定一个字符串s,找出其中的连续的最长的数字串。 答案:可以通过正则表达式来匹配数字串,然后使用max函数找出最长的。 代码示例: import re def find_longest_num_str(s): num_str_list = re.findall('\d+', s) longest_str = max(num_str_list, key=len) return longest_str s = "ab1234c56789def" print(find_longest_num_str(s)) 输出:56789 2. 练习题2: 题目:给定一个字符串s,将其中的每个空格替换为"%20"。 答案:可以通过正则表达式的sub函数来实现替换。 代码示例: import re def replace_space(s): new_s = re.sub(' ', '%20', s) return new_s s = "Hello World" print(replace_space(s)) 输出:Hello%20World 3. 练习题3: 题目:给定一个字符串s,判断它是否为回文字符串。 答案:可以使用切片操作将字符串反转,然后与原字符串进行比较。 代码示例: def is_palindrome(s): return s == s[::-1] s = "abcba" print(is_palindrome(s)) 输出:True ### 回答2: 以下是关于字符串和正则表达式练习题的答案: 1. 给定一个字符串s,编写一个函数,返回该字符串的反转字符串。 def reverse_string(s): return s[::-1] 2. 给定一个字符串s,编写一个函数,返回是否是回文字符串。 def is_palindrome(s): return s == s[::-1] 3. 给定一个字符串s和一个字符c,编写一个函数,返回字符串s中字符c的出现次数。 def count_char(s, c): return s.count(c) 4. 给定一个字符串s,编写一个函数,返回字符串s中的所有单词列表。 def split_words(s): return s.split() 5. 给定一个字符串s,编写一个函数,返回字符串s中的所有数字列表。 import re def extract_numbers(s): return re.findall(r'\d+', s) 这只是一些可能的答案,其中的解决方法可以有很多种。每个问题都有不同的解决方案,具体取决于个人的编程风格和需求。希望这些答案能够帮助你理解和学习Python中的字符串和正则表达式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值