C程序设计语言练习1-23 编写一个删除C语言程序中所有的注释语句

C程序设计语言练习1-23 编写一个删除C语言程序中所有的注释语句,要正确处理带引号的字符串与字符常量,以C语言中,注释不允许嵌套。

本程序运行后,将要求用户输入一个当前目录下的C源码程序文件名,读取后,将文件中的所有注释删除掉。

将另存为*_noc.ext文件,*中可以包含多个点,.ext可以为空(即没有文件扩展名)。

编辑C源码:

User@User-PC MINGW32 /d/mycode/c/krc
$ vim k0137.c

/* 读取一个C源码文件,将其中的注释全部删除掉,并保存为新文件*_noc.c */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXLEN 100 //文件名称最大长度
#define FILEMAXLEN 10000 //文件内容最大长度
int readline(char str[]);
int newfilename(char file[],int len);
int main(void){
    FILE *fp;
    char ch,file[MAXLEN],content[FILEMAXLEN];
    int len,i=0;
    int lastpos=-1;//第一个斜线的位置
    int iscomment=0;//是注释标志位
    int isstring=0;//是字符串内
    char strstart;//开始的字符串是单引号还是双引号
    printf("读取当前目录下的文本文件,请输入文件名:\n");
    while((len=readline(file))>0)   {
        if((fp=fopen(file,"rt"))==NULL){
            printf("文件打开错误,请重新输入:\n");
        }else{
            while((ch=fgetc(fp))!=EOF){
                if(isstring==1){
                    //字符串内,查找字符串结束字符,且其前一个字符不能是反斜线
                    if(ch==strstart&&content[i-1]!='\\'){
                        isstring=0;
                    }
                    content[i]=ch;
                    ++i;
                }else if(iscomment==2){
                    //多行注释,查找多行注释的结束符
                    if(ch=='/'){
                        if(i-lastpos==1){
                            iscomment=0;
                        }
                    }else if(ch=='*'){
                        lastpos=i;
                    }
                }else if(iscomment==1){
                    //单行注释,查找换行符
                    if(ch=='\n'){
                        iscomment=0;
                        content[i]=ch;
                        ++i;
                    }
                }else{
                    content[i]=ch;
                    if(ch=='*'){
                        if(i-lastpos==1){
                            iscomment=2;
                            i-=2;//多行注释的开始符号要删除
                        }
                    }else if(ch=='/'){
                        if(i-lastpos==1){
                            iscomment=1;
                            i-=2;//单行注释的两个斜线要删除
                        }else{
                            iscomment=0;
                            lastpos=i;
                        }
                    }else if(ch=='\''||ch=='"'){
                        isstring=1;
                        strstart=ch;
                    }
                    ++i;
                }
            }
            fclose(fp);
            content[i]='\0';//fputs写入文件的字符串以'\0'结束
            printf("\n\n新文件的内容:\n");
            i=0;
            while((ch=content[i])!='\0'){
                putchar(ch);
                ++i;
            }
            len=newfilename(file,len);
            printf("是否保存新文件%s?(y/n):",file);
            while((ch=getchar())!='y'&&ch!='n');
            if(ch=='y'){
                if(len>0){
                    fp=fopen(file,"w+");
                    fputs(content,fp);
                    fclose(fp);
                    printf("文件已成功保存!\n");
                    ch=getchar();
                }
            }
        }
        printf("请输入新的文件名:\n");
    }
    return 0;
}
/*
将文件名更改为*_noc.ext,.ext可以为空,*中可以包含点.
*/
int newfilename(char file[],int len){
    int i,j,c;
    int extflag=0,newlen=0;
    char newfile[MAXLEN];
    //printf("\nfile:%s,len:%d\n",file,len);
    for(i=len-1,j=0;i>=0;--i,++j){
        c=file[i];
        newfile[j]=c;
        if(extflag==0&&c=='.'){
            ++j;newfile[j]='c';
            ++j;newfile[j]='o';
            ++j;newfile[j]='n';
            ++j;newfile[j]='_';
            extflag=1;
        }
    }
    newfile[j]='\0';
    if(j==len){
        //文件没有后缀名称,则直接在后面加上_noc     
        i=len;
        file[i]='_';
        ++i;file[i]='n';
        ++i;file[i]='o';
        ++i;file[i]='c';
        ++i;
    }else{
        newlen=j;   
        for(i=0,j=newlen-1;j>=0;--j,++i){
            file[i]=newfile[j];
        }
    }
    file[i]='\0';
    return i;
}
/*
读取文件名,不需要后面的\n
*/
int readline(char str[]){
    int i,c;
    for(i=0;i<MAXLEN-1&&(c=getchar())!=EOF&&c!='\n';++i){
        str[i]=c;
    }
    str[i]='\0';
    return i;
}

编译生成可执行文件

User@User-PC MINGW32 /d/mycode/c/krc
$ gcc -o k0137 k0137.c

运行测试

User@User-PC MINGW32 /d/mycode/c/krc
$ ./k0137

读取当前目录下的文本文件,请输入文件名:
hello.c

新文件的内容:
#include <stdio.h>
int main(void){
    printf("hello world!\n");
    printf("世界你好!\n"); 
    return 0;
}
是否保存新文件hello_noc.c?(y/n):y
文件已成功保存!
请输入新的文件名:

User@User-PC MINGW32 /d/mycode/c/krc
$

hello.c文件内容:

User@User-PC MINGW32 /d/mycode/c/krc
$ vim hello.c

/* C源码文件:helloworld */
#include <stdio.h>
int main(void){
    printf("hello world!\n");
    printf("世界你好!\n");//查看显示中文是否正常
    return 0;
}

(全文完)

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ycjnx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值