第二十八课 字符串、字符数组、字符指针 【项目1-5】

第二十八课 字符串、字符数组、字符指针



项目一 【M$pszi$y是嘛意思?】
背景:小明让同学传纸条给小丽。小丽接到会心一笑,大家却不知所云。纸条上写着M$pszi$y,两人暗中约定是,真实字符为实际字符前面的第4个!M$pszi$y是神马意思?推算一下,或从ASCII码表中查一下,自然是I love u。
(1)小明请你写一个程序,在给小丽写情书时,再不用费功夫自己“翻译”,原信中每一个字符加密为其后的第4个字符。例,输入I love u,输出M$pszi$y。
(2)小丽请你写一个程序,在看小明的情书时,让程序帮着“解密”。因为有同学知道了他们俩人的“加密”手段,决定纸条由人传,加密数字(1-9)用两人约好的手势传,所以解密时,需要将加密数字作为程序输入。例,输入M$pszi$y(回车)4,输出I love u
(3)小刚常帮着传纸条,想知道俩人的秘密,但不知道加密数字,于是写了一个程序,可以列出所有可能的情况。例,输入M$pszi$y,多行输出中必然有一行是I love u。你就是小刚,写出这个程序来吧。

(1)代码:
#include<stdio.h>
int main()
{
    char a[50];
    int i;
    printf("输入原文:");
    gets(a);
    for(i=0;a[i]!='\0';i++)
        a[i]=a[i]+4;
    a[i]='\0';
    printf("\n密文为:");
    puts(a);
    return 0;
}
运行结果:



(2)代码:
#include<stdio.h>
int main()
{
    int i,num;
    char a[30];
    printf("输入密文:");
    gets(a);
    printf("输入加密数:");
    scanf("%d",&num);
    for(i=0;a[i]!='\0';i++)
        a[i]=a[i]-num;
    a[i]='\0';
    printf("译文为:");
    puts(a);
    return 0;
}
运行结果:


(3)代码:
#include<stdio.h>
void put(char a[],int n);
int main()
{
    int num;
    char a[30];
    printf("输入密文:");
    gets(a);
    printf("译文为:\n");
    for(num=1;num<9;num++)
        put(a,num);
    return 0;
}
void put(char a[30],int n)
{
    int i;
    char b[30];
    for(i=0;a[i]!='\0';i++)
        b[i]=a[i]-n;
    b[i]='\0';
    puts(b);
}
运行结果:




项目二【字符统计】
下面的程序可以统计出一个字符串中数字字符的个数:
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. int main()  
  3. {  
  4.     char str[50];  
  5.     int i=0,n=0;  
  6.     printf("输入字符串:");  
  7.     gets(str);  
  8.     while(str[i]!='\0')  
  9.     {  
  10.         if(str[i]>='0'&&str[i]<='9') n++;  
  11.         i++;  
  12.     }  
  13.     printf("其中的数字个数是: %d\n", n);  
  14.     return 0;  
  15. }  
请分别编制程序,完成下面的处理:
(1)统计字母'A'出现的次数;
(2)统计字符串中(大/小写)字母个数;
(3)统计每一个元音字母个数
(4)统计每一个数字字符出现的次数;
    提示:可以定义一个数组int a[10],保存’0’-’9’在字符串中出现的次数(例a[0]表示字符’0’的个数)
(5)统计每一个字母出现的个数

(1)代码:
#include<stdio.h>
int main()
{
    char str[50];
    int i=0,n=0;
    printf("输入字符串:");
    gets(str);
    while(str[i]!='\0')
    {
        if(str[i]=='A') n++;
        i++;
    }
    printf("其中字母‘A’的个数是:%d\n",n);
    return 0;
}
运行结果:

(2)代码:
#include<stdio.h>
int main()
{
    char str[50];
    int i=0,n=0,m=0;
    printf("输入字符串:");
    gets(str);
    while(str[i]!='\0')
    {
        if(str[i]>='A'&&str[i]<='Z')
            n++;
        else if(str[i]>='a'&&str[i]<='z')
            m++;
        i++;
    }
    printf("其中大写字母的个数是:%d\n",n);
    printf("其中小写字母的个数是:%d\n",m);
    return 0;
}
运行结果:

(3)代码:
#include<stdio.h>
int main()
{
    char str[50];
    int num[10]={0};
    int i=0,n;
    printf("输入字符串:");
    gets(str);
    while(str[i]!='\0')
    {
        if(str[i]>='0'&&str[i]<='9')
        {
            n=str[i];
            num[n]++;
        }
        i++;
    }
    i=0;
    while(i<10)
    {
        printf("%d: %d\n",i,num[i]);
        i++;
    }
    return 0;
}
运行结果:


(4)代码:
#include<stdio.h>
int main()
{
    char str[50];
    int num[10]={0};
    int i=0;
    printf("输入字符串:");
    gets(str);
    while(str[i]!='\0')
    {
        if(str[i]>='0'&&str[i]<='9')
        {
            num[str[i]-'0']++;
        }
        i++;
    }
    for(i=0;i<10;i++)
        printf("%d: %d\n",i,num[i]);
    return 0;
}
运行结果:

(5)代码:
#include<stdio.h>
int main()
{
    char str[100]={"Checking for existence: D:\\C\\codeBlock\\example\\bin\\Debug\\example.exe"};
    int num[26]={0};
    int i=0;
    puts(str);
    while(str[i]!='\0')
    {
        if(str[i]>='a'&&str[i]<='z')
        {
            num[str[i]-'a']++;
        }
        else if(str[i]>='A'&&str[i]<='Z')
            num[str[i]-'A']++;
        i++;
    }
    printf("各字母出现次数为:\n");
    i=0;
    while(i<26)
    {
        printf("%c: %d\n",(char)i+97,num[i]);
        i++;
    }
    return 0;
}
运行结果:




项目三 【字符串复制】
下面的程序,将str1中除空格外的所有字符,复制到了str2中。
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. int main()  
  3. {  
  4.     char str1[100]="I am a happy boy\'s daddy.",str2[100];  
  5.     int i=0,j=0;  
  6.     while(str1[i]!='\0')  
  7.     {  
  8.         if(str1[i]!=' ')  
  9.         {  
  10.             str2[j]=str1[i];  
  11.             j++;  
  12.         }  
  13.         i++;  
  14.     }  
  15.     str2[j]='\0';//切记!!  
  16.     printf("去除空格后的字符串: %s\n", str2);  
  17.     return 0;  
  18. }  
请分别编制程序,完成下面的处理:
(1)完整复制字符串;
(2)将str1和str2接起来存放到str3中;
(3)去除str1中的空格,仍保存在str1中;
(4)将str1和str2连接起来,仍存放在str1中;

(1)代码:
#include<stdio.h>
int main()
{
    char str1[100]="I am happy boy\'s daddy.",str2[100];
    int i=0,j=0;
    while(str1[i]!='\0')
    {
        str2[j++]=str1[i++];
    }
    str2[j]='\0';
    printf("%s\n",str2);
    return 0;
}

(2)代码:
#include<stdio.h>
int main()
{
    char str1[]={"I am a happy "};
    char str2[]={"boy\'s daddy."};
    char str3[100];
    int i=0,j=0,k=0;
    while(str1[i]!='\0')
        str3[k++]=str1[i++];
    while(str2[j]!='\0')
        str3[k++]=str2[j++];
    str3[k]='\0';
    puts(str3);
    return 0;
}

(3)代码:
#include<stdio.h>
int main()
{
    char str1[50]={"I am a boy."};
    int i=0,t=0;
    puts(str1);
    while(str1[i+t]!='\0')
    {
        str1[i]=str1[i+t];
        if(str1[i]==' ')
        {
            t++;
            continue;
        }
        i++;
    }
    str1[i]='\0';
    puts(str1);
    return 0;
}
运行结果:


(4)代码:
#include<stdio.h>
int main()
{
    char str1[40]={"I am a boy."};
    char str2[20]={"//注释:测试专用"};
    int i=0,j=0;
    while(str1[i]!='\0')
        i++;
    while(str2[j]!='\0')
    {
        str1[i++]=str2[j++];
    }
    str2[j]='\0';
    puts(str1);
    return 0;
}
运行结果:



项目四 【字符串处理函数】
指针是神奇的,指向整型的指针int *p1,可以操作整型数组int a[];指向字符型的指针char *p2,可以操作字符数组(字符串)char str[];更灵活的是,在函数的传递中,指针、数组名在一定程度上可以互换。请编制函数,对字符串的进行各种操作。

功能

用数组名作形参

用指针作形参

1

字符串str1str2连接,连接后的结果存放到str1

char *astrcat(char str1[], char str2[])

char *pstrcat(char *str1, char *str2)

2

去除字符串str中的特定字符c(如空格),结果仍保存到原字符串中

char *adelchar(char str[], char c)

char *pdelchar(char *str, char c)

3

求字符串str的长度并返回

int astrlen(char str[])

int pstrlen(char *str)

4

统计句子str中单词的个数

不再重重复,做右边的(下同)

int pwordnum(char *str)

5

去除句子中第一个单词前的空格,返回去除了空格的字符串

 

char *ptrim(char *str)

6

去除句子中所有多余的空格,返回去除了空格的字符串

 

char *palltrim(char *str)

7

比较两个字符串,返回值同strcmp()

 

int pstrcmp(const char *str1, const char *str2)


提示1:在完成任务时,自编main函数进行测试,测试中,给出的的实际参数可以是以’\0’结束的字符数组,也可以是指向字符的指针。
提示2:在实际项目中,通过包括string.h头文件,可以调用C语言中操作字符串的函数完成相关操作,而不必专门定义。


(1)代码和结果:
#include<stdio.h>
char *astrcat(char *str1,char *str2);
int main()
{
    char str1[100]={"Hello world,"};
    char str2[50]={"good morning!"};
    char *str_a=str1;
    char *str_b=str2;
    astrcat(str_a,str_b);
    printf("%s\n",str1);
    return 0;
}
char *astrcat(char *str1,char *str2)
{
    int i=0;
    char *p;
    for(p=str1;*p!='\0';p++);
    for(i=0;*(str2+i)!='\0';i++,p++)
    {
        *p=*(str2+i);
    }
    *p='\0';
    return str1;
}

(2)代码和结果:
#include<stdio.h>
char *adelchar(char str[],char c);
int main()
{
    char str[40]="Hello,I am Tom,what is your name?";
    adelchar(str,' ');
    printf("%s\n",str);
    return 0;
}
char *adelchar(char str[],char c)
{
    int i=0,j=0;
    while(str[j]!='\0')
    {
        if(str[j]!=' ')
        {
            str[i]=str[j];
            i++;
        }
        j++;
    }
    str[i]='\0';
    return 0;
}


(3)代码和结果:
#include<stdio.h>
int astrlen(char str[]);
int main()
{
    char str[40]="Hello world!";
    puts(str);
    printf("%d\n",astrlen(str));
    return 0;
}
int astrlen(char str[])
{
    int i;
    for(i=0;str[i]!='\0';i++);
    return i;
}

(4)代码和结果:
#include<stdio.h>
int pwordnum(char *str);
int main()
{
    char str[80]="My phone number is:123456.one,tow,three,F,f and s!";
    puts(str);
    printf("共%d个单词\n",pwordnum(str));
    return 0;
}
int pwordnum(char *str)
{
    int i=0,n=0,t=1;
    for(i=0;*(str+i)!='\0';i++)
    {
        if(((*(str+i)>='a'&&*(str+i)<='z')||(*(str+i)>='A'&&*(str+i)<+'Z'))&&(*(str+i)!='\0'))
        {
            t=1;
        }
        else if(t==1)
        {
            t=0;
            n++;
        }
    }
    return n;
}


(5)代码和结果:
#include<stdio.h>
char *ptrim(char *str);
int main()
{
    char str[20]="    I am Tom.";
    puts(str);
    printf("去除空格后为:\n%s\n",ptrim(str));
    return 0;
}
char *ptrim(char *str)
{
    char *p=str,*q=str;
    for(p=str;*p==' ';p++);
    while(*p!='\0')
        *q++=*p++;
    *q='\0';
    return str;
}



(6)代码和结果:
#include<stdio.h>
char *palltrim(char *str);
int main()
{
    char str[30]="  I   have   a   dream.";
    puts(str);
    printf("去除多余的空格后显示为:\n%s\n",palltrim(str));
    return 0;
}
char *palltrim(char *str)
{
    int k=0;
    char *p=str,*q=str;
    for(q=str;*q!='\0';q++)
    {
        if(*q!=' '||k)
        {
            *p=*q;
            p++;
        }
        if(*q!=' ')
            k=1;
        else
            k=0;
    }
    *p='\0';
    return str;
}



(7)代码和结果:
#include<stdio.h>
int pstrcmp(char *str1,char *str2);
int main()
{
    char str1[20]="apple";
    char str2[20]="orange";
    int n;
    puts(str1);
    puts(str2);
    n=pstrcmp(str1,str2);
    if(n==1)
        printf("%s最大\n",str1);
    else if(n==-1)
        printf("%s最大\n",str2);
    else if(n==0)
        printf("两字符串相等\n");
    return 0;
}
int pstrcmp(char *str1,char *str2)
{
    char *p=str1,*q=str2;
    int n=0;
    while(*p==*q&&*p!='\0'&&*q!='\0')
        if(*p==*q)
        {
            p++;
            q++;
        }
    if(*p>*q)
        n=1;
    else if(*p<*q)
        n=-1;
    return n;
}



项目五 【编程处理C++源代码】
在CodeBlocks等IDE中都提供了代码格式整理的功能。我们可以编写程序,处理的数据就是用C写的源代码文件。C源文件是一种文本文件,可以通过程序进行操作。
(1)读入一个C程序,判断其中是否只有一个main()函数,输出“暂时没有发现问题”,或者“没有main()函数”,或者“不能定义多个main()函数”;
提示1:简单处理,可以只比较判断“main()”,考虑实际上的各种可能,main后面的括号中还有其他多种写法。建议按最简单的情形处理。
提示2:建议设计一个函数,将读到的代码与字符串“main()”进行比较。函数用于判断s1是否“包含”在读入的一行s2中,调用时,形参s1处的实参用“main()”即可,这样写提升了“抽象”级别,更容易实现,对应更高的代码质量。
(2)编写一个程序并取名test.c,统计该文件中出现"if","while","for"的次数。
(3)读入一个C程序,使程序中的所有左花括号“{”和右花括号“}”都单独占一行,新程序保存到另一个.c文件中,并在屏幕上显示处理过的程序,显示时加上行号。
(4)读入一个C程序,输入m、n两个数字,从第m行起的n行代码将作为注释使用(即在这些行前面加上”//”),新程序保存到另一个.c文件中。

(1)代码和结果:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int mainstr(char *line,char *str);
int main()
{
    char str[7]="main()";
    char line[256];
    int num=0;
    FILE *p=fopen("test.c","r");
    if(p==NULL)
    {
        printf("file cannot open!\n");
        exit (1);
    }
    while(!feof(p))
    {
        fgets(line,256,p);
        num+=mainstr(line,str);
        if(num>1)
            break;
    }
    fclose(p);
    if(num==0)
        printf("缺少main函数!\n");
    else if(num==1)
        printf("main函数正常\n");
    else
        printf("main函数超过限制!\n");
    return 0;
}
int mainstr(char *line,char *str)
{
    int n=0,k;
    char *p,*t;
    while(*line!='\0')
    {
        if(*line==*str)
        {
            k=1;
            p=line;
            t=str;
            while(*t!='\0')
            {
                if(*t++!=*p++)
                {
                    k=0;
                    break;
                }
            }
            if(k==1)
                n++;
        }
        line++;
    }
    return n;
}
例文件:


(2)代码和结果:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int fun_num(char *line,char *key);
int main()
{
    char line[256];
    char ifstr[6]="if";
    char whilestr[6]="while";
    char forstr[6]="for";
    int if_num=0,while_num=0,for_num=0;
    FILE *p=fopen("test.c","r");
    if(p==NULL)
    {
        printf("open error!");
        exit(0);
    }
    while(!feof(p))
    {
        fgets(line,256,p);
        if_num+=fun_num(line,ifstr);
        while_num+=fun_num(line,whilestr);
        for_num+=fun_num(line,forstr);
    }
    fclose(p);
    printf("if出现%d次,while出现%d次,for出现%d次\n",if_num,while_num,for_num);
    return 0;
}
int fun_num(char *line,char *key)
{
    int n,num=0;
    char *p,*q;
    while(*line!='\0')
    {
        if(*line==*key)
        {
            n=1;
            p=line;
            q=key;
            while(*q!='\0')
            {
                if(*q!=*p)
                {
                    n=0;
                    break;
                }
                p++;
                q++;
            }
            if(n==1)
                num++;
        }
        line++;
    }
    return num;
}
检测代码(1)的结果:

(3)代码和结果:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void funstr(char *test1,char *test2);
void putstr(char *test);
int main()
{
    funstr("test1.c","test2.c");
    printf("输出结果为:\n");
    putstr("test2.c");
    printf("\n\n结果保存在test2.c中\n");
    return 0;
}
void funstr(char *test1,char *test2)
{
    char c1,c2;
    FILE *pin=fopen(test1,"r");
    FILE *pout=fopen(test2,"w");
    if(pin==NULL||pout==NULL)
    {
        printf("open error!\n");
        exit(0);
    }
    c1='\0';
    while(!feof(pin))
    {
        c2=fgetc(pin);
        if((c2=='{'||c2=='}')&&(c1!='\n'))
            fputc('\n',pout);
        else if((c1=='{'||c1=='}')&&(c2!='\n'))
            fputc('\n',pout);
        c1=c2;
        fputc(c2,pout);
    }
    fclose(pin);
    fclose(pout);
}
void putstr(char *test)
{
    int n=1;
    char line[256];
    FILE *p=fopen(test,"r");
    if(p==NULL)
    {
        printf("error!\n");
        exit(0);
    }
    while(!feof(p))
    {
        printf("%d    ",n);
        fgets(line,256,p);
        printf("%s",line);
        n++;
    }
    fclose(p);
}



(4)代码和结果:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void putfun(int m,int n);
int main()
{
    int m,n;
    printf("请输入m,n:");
    scanf("%d %d",&m,&n);
    putfun(m,n);
    return 0;
}
void putfun(int m,int n)
{
    char line[256];
    int i=0;
    FILE *pin=fopen("test1.c","r");
    FILE *pout=fopen("test2.c","w");
    if(pin==NULL||pout==NULL)
    {
        printf("error!\n");
        exit(0);
    }
    while(!feof(pin))
    {
        fgets(line,256,pin);
        i++;
        if(i>=m&&i<m+n)
        {
            fputs("//",pout);
        }
        fputs(line,pout);
    }
    printf("right!\n");
    fclose(pin);
    fclose(pout);
}
修改结果:







  字符串最后一定要加'\0'作为字符串的结束,切记
  本课出现了很多重要的算法,好好理解消化







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值