C和指针之学习笔记(4)

第9章 字符串

  1. 字符串的输入与输出

int  ch;  char strings[80];  FILE *input;

(1)scanf(“%c”,&ch);   printf(“%c \n”,ch);    (输入字符串时自动添加\0

(2)ch = getchar();   putchar(ch);

(3)gets( strings );    puts( strings );      (输入字符串时自动添加\0

(4)fgets( strings, 80, stdin);    fputs( strings, stdout);

(5)fscanf (input, “%d %d”, &a , &b );

fprintf (input, “%d %d”, a , b );

(6)ch = getc ( input );   putc ( ch, input );

(7)sprintf() 主要针对字符串操作

1)数字字符串操作:sprinf( strings, “%d%d”,124,243); 产生字符串:124243

2)控制浮点数打印格式:%f 默认保留小数点后6位,

sprintf(strings, “%f”,3.1415923); 产生:3.141593

3)连接字符串:在许多场合可以替代strcat()函数

char *who=”I”;  char *whom=”English”;

sprintf(strings, “%s love %s”,who, whom);

结果:I love English

4)返回本次函数调用最终打印到字符缓冲区的字符数目

    

     (8)sscanf() 可以从字符串中取出整数、浮点数和字符串等。

1)提取字符串:sscanf( “123456”, “%s”, strings);  strings: 123456

2)指定长度的字符串:sscanf( “123456”, “%4s”, strings);  strings: 1234

3)取到指定字符串为止的字符串

sscanf( “123456 abdcdef”, “%[^ ]”, strings);  strings: 123456

4)仅包含指定字符集的字符串:(取仅包含1-9和小写字母的字符串)

sscanf( “123456abdDJKJKELW”, “%[1-9a-z]”, strings);  strings: 123456abd

5)到指定字符集为止的字符串

sscanf( “123456abdDJKJKELW”, “%[^ A-Z]”, strings);  strings: 123456abd

2.复制: char  *strcpy ( char * dst, char const *src );  返回指向目标字符数组的指针,即dst。

3.连接char  *strcat ( char * dst, char const *src );  返回指向目标字符数组的指针,即dst。

4.比较int  strcmp (char const * s1, char const *s2 );  若s1<s2,返回负数;若s1>s2,返回正数;若s1=s2,返回0;

5.长度受限字符串函数

(1)char  *strncpy( char *dst, char const *src, size_t len);  //若strlen(src)小于len,dst数组就用额外的NULL字节填充到len长度。

(2)char  *strncat( char *dst, char const *src, size_t len);

(3)int  strncmp( char const *s1, char const *s2, size_t len);

 

6.查找一个字符

(1)char  *strchr( char const *str, int ch);  //返回str中ch第一次出现的位置

(2)char  *strrchr( char const *str, int ch);  // 返回str中ch最后一次出现的位置

7.查找几个字符

char  *strpbrk (char const *str, char const *group);

返回str中第一个匹配group中任何一个字符的位置,若未找到匹配,返回NULL。

eg: char  string [20] = “ Hello there, honey.”;

char  *ans;

ans=strpbrk ( string , “aeiou”);

ans指向的位置都是string+1.

8.查找一个子串

char  *strstr ( char const *s1, char const *s2 );

在s1中查找s2第1次出现的起始位置,并返回指向该位置的指针。若s2是空,返回s1.

9.查找一个字符串前缀

size_t  strspn ( char const *str, char const *group );  //返回str起始部分匹配group中任意字符的字符数。

size_t  strcspn ( char const *str, char const *group);  //与strspn正好相反

eg:(1)

int  len1, len2;

char  buffer [] = “25,142,330,Smith,J,239-4123”;

len1=strspn ( buffer, “0123456789” );

len2=strspn ( buffer, “,0123456789” );

len1的值为2,len2的值为11

(2)

计算一个指向字符串中旳第一个非空白字符的指针:

ptr = buffer + strspn (buffer, “\n\r\f\t\v” );

10.查找标记

char  *strtok ( char *str, char const *sep );   

sep参数是个字符串,定义了用作分隔符的字符集合。第一个参数指定一个字符串,它包含0个或多个由sep中一个或多个分隔符分隔的标记。strtok找到str的下一个标记,并将其用NULL结尾,然后返回一个指向这个标记的指针。

11.C primer plus 11-7

  编写一个函数string_in(),它接受两个字符串指针参数。如果第二个字符串被包含在第一个字符串中,函数就返回被包含的字符开始的地址。例如,string_in("hats","at")返回hats中a的地址,则,函数返回空指针。在一个使用循环语句为这个函数提供输入的完整程序中进行测试。

#include <stdio.h>

char *string_in(char *p1, char *p2);

int main(void)

{

char str1[81];

char str2[21];

char *p;

do

{

puts("input range string:");

gets(str1);

puts("input match string:");

gets(str2);

p = string_in(str1, str2);

if ( p )

{

puts("Find!");

puts(p);

}

else puts("Can‘t find!");

puts("input any char except q to go on.");

gets(str1);

}

while(*str1 != ‘q‘);

puts("Quit.");

return 0;

}

char *string_in(char *p1, char *p2)

{

char *p1_save = p1, *p2_save = p2;

if(*p1 == ‘\0‘ || *p2 == ‘\0‘) return NULL;

while(1)

{

if(*p1 == *p2)

{

 if(*++p2 == ‘\0‘) return p1_save;  //此时应用++p2

   if(*++p1 == ‘\0‘) return NULL;

 

}

else

{

if(*++p1 == ‘\0‘) return NULL;

 p1_save = p1;

   p2 = p2_save;  //若遇到*p1和*p2不同,且*p1不为0,则p2指向首字母,重新在p1中寻找,p1从当前位置开始向后移动。

}

}

}

12.C primer plus 11-10

 

.编写一个程序,读取输入,直到读入了10个字符串或遇到EOF,由二者中最先被满足的那个终止读取过程。这个程序可以为用户提供一个有5个选项的菜单:输出初始字符串列表、按ASCII顺序输出字符串、按长度递增顺序输出字符串、按字符串中第一个单词的长度输出字符串和退出。菜单可以循环,直到用户输入退出请求。当然,程序要能真正完成菜单中的各项功能。

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#define LINE 10

#define SIZE 81

void strinit(char *strings[],int num);

void strsrt(char *strings[],int num);

void strlong(char *strings[],int num);

void strwordlen(char *strings[],int num);

void menu();

int main()

{

char input[LINE][SIZE];

char *ptr[LINE];

int ct=0;

int choose;

printf("Input up to %d lines:\n",LINE);

while(ct<LINE && gets(input[ct])!=NULL && input[ct][0]!=‘\0‘)

{

ptr[ct]=input[ct];

ct++;

}

puts(" ");

puts("Please choose the way to sort: (1-5)");

menu();

printf("Please input your choice : ");

scanf("%d",&choose);

while(choose!=5)

{

switch(choose)

{

case 1:strinit(ptr,LINE);

break;

case 2:strsrt(ptr,LINE);

break;

case 3:strlong(ptr,LINE);

break;

case 4:strwordlen(ptr,LINE);

break;

default :break;

}

puts(" ");

puts("Please choose the way to sort: (1-5)");

menu();

printf("Your choice is : ");

scanf("%d",&choose);

}

return 0;

}

void menu()

{

puts("*******************************");

puts("1.输出初始化字符串列表.");

puts("2.按照ASCII顺序输出.");

puts("3.按照长度递增输出.");

puts("4.按字符串中第一个单词长度输出.");

puts("5.退出.");

puts("*******************************");

}

void strinit(char *strings[],int num)   //初始化字符串,并输出

{

for(int i=0;i<LINE;i++)

puts(strings[i]);

}

void strsrt(char *strings[],int num)    //按照首字母输出字符串

{

char *temp;

int top,seek;

for(top=0;top<num-1;top++)

for(seek=top+1;seek<num;seek++)

if(strcmp(strings[top],strings[seek])>0)

{

temp=strings[top];

strings[top]=strings[seek];

strings[seek]=temp;

}

/* for(int i=0;i<num;i++)

puts(strings[i]); */

strinit(strings,num);   //直接用strinit()

}

void strlong(char *strings[],int num)    //按照字符串长度输出字符串

{

int i,j;

char *temp;

for(i=0;i<num-1;i++)    //冒泡排序

for(j=0;j<num-1-i;j++)

{

if(strlen(strings[j])>strlen(strings[j+1]))

{

temp=strings[j];

strings[j]=strings[j+1];

strings[j+1]=temp;

}

}

//for( i=0;i<num;i++)

// puts(strings[i]);

strinit(strings,num);

}

void strwordlen(char *strings[],int num)   //按照首单词长度输出字符串

{

int i,j,flag;

int number[10];

char *temp;

for(i=0;i<num;i++)

{

j=0;

while(strings[i][j]!=‘ ‘ && strings[i][j]!=‘\n‘ && strings[i][j]!=‘\0‘)

j++;

number[i]=j;

}

for(i=0;i<num;i++)

printf("the number is : %d\n",number[i]);

for(i=0;i<num-1;i++)      //冒泡排序

for(j=0;j<num-1-i;j++)

{

//printf(" is : %d\n",number[j]);

//  printf("number is : %d\n",number[j+1]);

if(number[j]>number[j+1])

{

flag=number[j];              //没有这段代码时,无法进行字符串交换

number[j]=number[j+1];

number[j+1]=flag;

//只有number里面的数值进行了交换,才可以引导字符串进行交换,否则就是错误的

temp=strings[j];

strings[j]=strings[j+1];

strings[j+1]=temp;

}

}

strinit(strings,num);

}

13.C primer plus 11-12

编写一个程序,按照相反的单词顺序显示命令行参数。即,如果命令行参数是see you later,程序的显示应该为later you see

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void reverse(char *input,char *output);

int main()

{

char input[80];             //input为指针常量,不能自加和自减

char *output;

output=(char *)malloc(sizeof(char *));   //很重要,指针变量不能自动分配存储空间

puts("Please input your strings:");

 fgets(input,80,stdin);

 

reverse(input,output);

puts("Now your strings are:");

puts(output);

return 0;

}

void  reverse(char *input,char *output)

{

char *pt;

pt=input;

while(*pt!=‘\0‘)     不能用while(*pt++!=‘\0‘);

pt++ ;

//   putchar(*pt++);

pt--;

for( int i=0; i<strlen(input) && pt>0; i++)

{

output[i]=*pt;

// putchar(output[i]);

pt--;

}

output[strlen(input)]=‘\0‘; //一定得加上‘\0‘,因为puts默认是80,若不加,会自行乱码填充

// puts(output);

}

char * reverse(char *input)   //这段代码错误原因就是局部变量在函数结束时内存已经收回,

{                       //无法将指针进行传递

char *pt,*tr,*pr;

int i=0,j=0;

pt=input;

while(*pt!=‘\0‘)

pt[i++];

tr=&pt[i-1];

putchar(*tr);

while(*tr!=‘\0‘)

{

pr[j++]=*tr--;

}

return pr;

}

14.fgets和scanf区别

char *string;    

char *pt;

string=(char *)malloc(sizeof(char *));

puts("Please input your string:");

scanf("%s",string);   // fgets(string,80,stdin);

pt=string;

while(*pt!=‘\0‘)

pt++;

pt=pt-1;     // pt=pt-2;

putchar(*pt);

用scanf(红色)输入时,输出最后一个字符只需pt-1,而用fgets(蓝色)输入时,输出最后一个字符必须用pt-2

第10章 动态内存分配

1.malloc()分配一块连续内存,返回一个指向被分配的内存块起始位置的指针。(stdlib.h)

2.free()参数必须是NULL,或者是从malloc、calloc或realloc返回的一个值。

   void  free(void  * pointer);

3.void  *malloc(size_t  size);

void  *calloc(size_t  num_elements,size_t  element_size);

malloc和calloc区别:

(1)malloc参数是需要分配的内存字节数,calloc参数是需要分配的元素个数和每个元素的长度。

(2)calloc在返回前把内存初始化为0,而malloc返回时内存并未以任何形式进行初始化。

4.realloc函数用于修改一个原先已经分配的内存块的大小。使一块内存扩大或缩小。

5.复制字符串

#include<stdio.h>

#include<string.h>

char  * strdup (char  const  *string)

{

char  *new_string;

new_string = malloc ( strlen (string ) + 1 );

if ( new_string != NULL )

strcpy( new_string, string );

return  new_string;

}

时间: 2024-10-31 22:34:00

C和指针之学习笔记(4)的相关文章

【C++】--关于指针的学习笔记

1.指针的定义 指针(pointer)是指向另外一种类型的复合类型,与引用类似,指针也实现了对其他对象的间接访问. 与引用不同的几点: 1.指针本身就是一个对象,允许对指针赋值和拷贝,而且在指针的生命周期内它可以先后指向几个不同的对象. 2.指针不一定要在定义时赋初值. note:在块作用域内定义的指针如果没有被初始化,也将拥有一个不确定的值. 3. ...(待之后的学习实践中补充) 2.定义指针类型的方法 定义指针类型的方法是在变量名前面添加[*]星号,即将声明符写成[*d]的形式,d是变量名

《C和指针》学习笔记(1)

最近C语言已经学完,布置的大作业:学生管理系统5个版本也完成了.但是又买了一本<C和指针>,主要是感觉自己的指针还是没有完全熟悉.所以还是要好好研究一下.闲话不多说,直接第一章.一看是快速入门,以为很简单,但那个程序就把我卡了半天才看懂,按照作者说的的确运用了C语言中的大部分技巧. 程序1.1:首先读取一串列标号,这些列标号成对出现,便是输入行的列范围.这串列标号以一个负值结尾,作为结束标志.剩余的输入行被程序读入并打印,然后输入行中被选中范围的字符串被提取出来打印. 书中代码如下: #inc

智能指针_auto_ptr2_学习笔记

//1,release函数只是简单的转移对内存的拥有权,自己变成null,不会delete,一般在将所有权转移给别的智能指针的时候使用.具体可参加源码. 例: #include <memory> #include <iostream> using namespace std; class A { public:  A(int a):m_na(a)  {      cout<<"A cont" <<endl;  }  virtual ~A(

《C和指针》学习笔记(4)

进入<pointer on C>的第二章,不过感觉这一章没讲什么实质性的内容,主要是一些风格.字符以及一些古老的东西(比如三字母词)自己也不是很感兴趣.不过也算是了解一下C的历史了吧.不过问题和程序还是好好看了看. 比如又知道了一些转义字符: \?在书写多个分号的情况下使用,防止被解释为三字母词. \”用于表示一个字符串常量内部的双引号. \’用于表示字符常量. \\用于表示一个\ 写了一个例子: #include <stdio.h> #include <stdlib.h&g

《C和指针》学习笔记(2)

1.1  "hello world"程序不说了,codeblocks直接生成. 1.2   题目:从标准输入读取几行输入.每行输入都要打印到标准输出上,前面要加上行号.让程序能够处理的输入行没有长度限制. /*我的程序*//* int main() { int ch; int line=1; while((ch=getchar())!=EOF) { printf("%d",line); if(ch!='\n') printf("%c",ch);

C和指针之学习笔记(3)

第8章 数组 1.数组与指针 数组名是一个指针常量,也就是数组第1个元素的地址. int  a[10];  int  b[10];  int  *c; (1) c = & a[0]; &a[0]表示一个指向数组第1个元素的指针. (2) c=a; 与 c = & a[0]; 等价 (3) b = a; 非法,不能使用赋值符把一个数组的所有元素复制到另一个数组,必须使用一个循环,每次复制一个元素. (4) a = c; 非法,a是指针常量,而c是指针变量. 2. 下标引用和间接访问完

《深入理解C指针》学习笔记(1)--- 指针之外

C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是受到几乎所有程序员的肯定.C语言的这种灵活性很大一部分程度来源与C指针,指针为C语言动态操控内存提供了支持,同时也便于访问硬件.由于编程的本质就是操控数据,而数据大多都在内存中,理解C管理内存的工作原理,就显得尤为重要了.知道malloc()函数能够从堆上申请内存,理解内存分配的本质则是另外的事. 请看代码例子: 1 #include <stdio.h> 2 #include <stdlib.h>

C和指针之学习笔记(6)

第17章 经典数据结构类型 堆栈 堆栈接口提供三种基本的操作:push.pop 和 top. Push:把一个新值压入到堆栈的顶部. Pop: 只把顶部元素从堆栈中移除,它并不返回这个值. Top: 返回顶部元素的值,但它并不把顶部元素从堆栈中移除.   (1)堆栈接口 #ifndef STACK_H #define STACK_H #include<stdlib.h> #define STACK_TYPE int //push 把一个新值压入到堆栈中,它的参数是需要被压入的值 void pu

C和指针之学习笔记(5)

第10章 使用结构和指针 单链表 typedef struct NODE { struct NODE *link; int value; } Node; 插入到一个有序单链表: #include<stdio.h> #include<stdlib.h> #include "sll_node.h" #define FALSE 0 #define TRUE 1 int sll_insert( Node **linkp, int new_value)  //指针的指针