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 );      輸入字符串時自動添加\0ui

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

 

(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); 產生字符串:124243element

       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)返回本次函數調用最終打印到字符緩衝區的字符數目

    

     (8sscanf() 能夠從字符串中取出整數、浮點數和字符串等。

        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);  //strlensrc)小於lendst數組就用額外的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);  //返回strch第一次出現的位置

(2)char  *strrchr( char const *str, int ch);  // 返回strch最後一次出現的位置

 

7.查找幾個字符

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

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

egchar  string [20] = 「 Hello there, honey.」;

     char  *ans;

     ans=strpbrk ( string , 「aeiou」);

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

 

8.查找一個子串

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

s1中查找s21出現的起始位置,並返回指向該位置的指針。若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的值爲2len2的值爲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")返回hatsa的地址,則,函數返回空指針。在一個使用循環語句爲這個函數提供輸入的完整程序中進行測試。

#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.fgetsscanf區別

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,或者是從malloccallocrealloc返回的一個值。     

   void  freevoid  * pointer);

3.void  *mallocsize_t  size);

   void  *callocsize_t  num_elementssize_t  element_size);

malloccalloc區別

(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;

  }

相關文章
相關標籤/搜索