C++实践参考——处理C++源代码的程序

【项目 - 处理C++源代码的程序】

  在CodeBlocks等IDE中都提供了代码格式整理的功能。完成这种功能的程序,操作的数据是用C++写的源代码文件。C++源文件是一种文本文件,可以通过程序进行操作。
集成开发环境(IDE)对对程序进行编译,操作的“数据”是源程序。编译中,要对源程序进行词法检查和语法检查,后续还要进行目标代码生成、代码优化等工作。相关的技术将在《编译原理》课中学习。这些技术可以用在很多领域,当然也能够让我们对于编程语言有更深的了解。
  本项目将以C++源程序为操作对象,完成对源程序的一系列处理。各功能可以分别编制一个程序实现(建议用这种简单的方案),也可以将其集成在一起(向着自己做出IDE努力)。
(1)读入一个C++程序,判断其中是否只有一个main()函数,输出“暂时没有发现问题”,或者“没有main()函数”,或者“不能定义多个main()函数”;
提示1:简单处理,可以只比较判断”main()”,考虑实际上的各种可能,main后面的括号中有任意多个空格及void的都应该算在内。建议按最简单的情形处理。
提示2:建议设计一个函数,将读到的代码与字符串”main()”进行比较。函数用于判断s1是否“包含”在读入的一行s2中,调用时,形参s1处的实参用”main()”即可,这样写提升了“抽象”级别,更容易实现,对应更高的代码质量。
【参考解答】

#include <fstream>
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int appear(char*s1,char*s2);
int main( )
{
    char line[256];
    char main_fun[8]="main()";
    int main_num=0;//初时,尚未发现

    //将文件中的数据读入到字符数组中
    ifstream sourceFile("source.cpp",ios::in);  //以输入的方式打开文件
    if(!sourceFile)       //测试是否成功打开
    {
        cerr<<"source code read error!"<<endl;
        exit(1);
    }
    while(!sourceFile.eof())
    {
        sourceFile.getline(line,255,'\n');
        main_num+=appear(line,main_fun);
        if (main_num>1)  //多于1个,没有必要再去读取
            break;
    }
    sourceFile.close();

    //识别结论
    if(main_num==0)
        cout<<"error: no main().";
    else if (main_num==1)
        cout<<"right: a main() be exist.";
    else
        cout<<"error: more than one main().";
    cout<<endl;
    return 0;
}

//返回s2在s1中出现了几次
int appear(char*s1,char*s2)
{
    int n=0,flag;
    char *p,*q;
    for(; *s1!='\0'; s1++)
    {
        if (*s2==*s1) /*判断字符串中是否有和要判断的字串首字符相同的字符*/
        {
            flag=1;
            p=s1 ; /*s1 p 为第一个相同字符的地址*/
            q=s2;
            for(; *q!='\0';) /*如果有则判断接下去的几个字符是否相同*/
            {
                if (*q++!=*p++)
                {
                    flag=0;
                    break;
                }
            }
            if (flag==1) n++;
        }

    }
    return(n);
}

(2)读入一个C++程序,使程序中的所有左花括号“{”和右花括号“}”都单独占一行,新程序保存到另一个.cpp文件中,并在屏幕上显示处理过的程序,显示时加上行号。

[参考解答]

#include <fstream>
#include<iostream>
//#include<string>
#include<cstdlib>
using namespace std;
void outprogram(char *filename);
int main( )
{
    char ch1,ch2;
    //将文件中的数据读入到字符数组中
    ifstream sourceFile("source.cpp",ios::in);  //以输入的方式打开文件
    if(!sourceFile)       //测试是否成功打开
    {
        cerr<<"source code read error!"<<endl;
        exit(1);
    }
    ofstream outFile("newsource.cpp",ios::out);  //以输出的方式打开文件
    if(!outFile)       //测试是否成功打开
    {
        cerr<<"new source code write error!"<<endl;
        exit(1);
    }

    ch1='\0';
    while(!sourceFile.eof())
    {
        sourceFile.get(ch2);
        //读到了花括号,且前一个符号不是换行,应该加入一个换行
        if((ch2=='{'||ch2=='}')&&(ch1!='\n'))
            outFile.put('\n');
        else
            //当前读到的不是换行,但前一个是花括号,此时也该加
            if((ch1=='{'||ch1=='}')&&(ch2!='\n'))
                outFile.put('\n');
        outFile.put(ch2); //输出当前读入的符号
        ch1=ch2;
    }
    outFile.close();
    sourceFile.close();
    cout<<"经过处理后的源程序是:"<<endl;
    outprogram("newsource.cpp");
    return 0;
}

void outprogram(char *filename)
{
    char line[256];
    int n = 1;
    ifstream inFile(filename, ios::in);  //以输入的方式打开文件
    if(!inFile)       //测试是否成功打开
    {
        cerr<<"file open error!"<<endl;
        exit(1);
    }
    while (!inFile.eof())
    {
        inFile.getline(line,255,'\n');
        cout<<n<<'\t'<<line<<endl;
        n++;
    }
    inFile.close();
    return;
}

(3)读入一个C++程序,输入m、n两个数字,从第m行起的n行代码将作为注释使用(即在这些行前面加上”//”),新程序保存到另一个.cpp文件中,并在屏幕上显示处理过的程序,显示时加上行号。

[参考解答]

#include <fstream>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
void outprogram(const char *filename);
int main( )
{
    char line[256];
    int m,n;
    //将文件中的数据读入到字符数组中
    ifstream sourceFile("source.cpp",ios::in);  //以输入的方式打开文件
    if(!sourceFile)       //测试是否成功打开
    {
        cerr<<"source code read error!"<<endl;
        exit(1);
    }
    ofstream outFile("newsource.cpp",ios::out);  //以输出的方式打开文件
    if(!outFile)       //测试是否成功打开
    {
        cerr<<"new source code write error!"<<endl;
        exit(1);
    }
    cout<<"您要将第m行开始的n行代码作为注释,请输入m和n:";
    cin>>m>>n;
    int n1=0;
    while(!sourceFile.eof())
    {
        sourceFile.getline(line,255,'\n');
        n1++;
        if(n1>=m&&n1<m+n)
            outFile.put('/').put('/');
        outFile.write(line,strlen(line));
        outFile.write("\n",1);
    }
    outFile.close();
    sourceFile.close();
    cout<<"经过处理后的源程序是:"<<endl;
    outprogram("newsource.cpp");
    return 0;
}

void outprogram(const char *filename)
{
    char line[256];
    int n = 1;
    ifstream inFile(filename, ios::in);  //以输入的方式打开文件
    if(!inFile)       //测试是否成功打开
    {
        cerr<<"file open error!"<<endl;
        exit(1);
    }
    while (!inFile.eof())
    {
        inFile.getline(line,255,'\n');
        cout<<n<<'\t'<<line<<endl;
        n++;
    }
    inFile.close();
    return;
}

(以下参考略)
文字处理领域能做的工作也就此向大家敞开大门,下面一些功能作为选做内容,请有余力的同学参考,想。
(4)(选做)读入一个C++程序,将程序中的所有注释(包括//形式和/*...*/形式的)删除,新程序保存到另一个.cpp文件中,并在屏幕上显示处理过的程序,显示时加上行号。
(5)(选做)读入一个C++程序,使程序中:(1)所有左花括号“{”和右花括号“}”都单独占一行;(2)每个语句单独占一行;(3)各行采用统一的缩格排放(每遇一个“{”,其下一行的程序,在第一个有意义的符号前的空格数增加4(也可以是增加一个’\t’),每遇一个“}”,其下一行的程序,在第一个有意义的符号前的空格数减少4(也可以是一个’\t’))。
(6)(选做)基于(5),用wxWidgets设计界面,在对话框中选择要处理的源文件名,并指定目标文件名后进行处理。如在左图中点击按钮“…”后,会利用“打开文件对话框”(wxFileDialog)窗口选择文件。 

时间: 2024-10-21 13:06:31

C++实践参考——处理C++源代码的程序的相关文章

《C语言及程序设计》实践参考——用命令行运行程序

返回:贺老师课程教学链接 [项目1-用命令行运行程序]下面的程序,用于复制命令行中给出的文件.请利用命令行的方式运行程序. #include<stdio.h> #include<string.h> int main(int argc,char *argv[]) { FILE *p1,*p2; int c; p1=fopen(argv[1], "r"); p2=fopen(argv[2], "w"); while((c=fgetc(p1))!=

《C语言及程序设计》实践参考——处理C语言源代码的程序

返回:贺老师课程教学链接 [项目3 - 处理C语言源代码的程序] 用C语言写的源程序是一种文本文件.本项目将以C语言的源程序为操作对象,完成对源程序的一系列处理,如判断是否有main函数.将某些行加上注释等.各功能可以分别编制一个程序实现(建议用这种简单的方案),也可以将其集成在一起(向着自己做出IDE努力). (1)读入一个C++程序,判断其中是否只有一个main()函数,输出"暂时没有发现问题",或者"没有main()函数",或者"不能定义多个main

用Shell扩展实现源代码统计程序

一.前言 在 Windows 的资源管理器窗口中,我们见过 WinZIP,WinRAR 等软件能在文件或文件夹的默认快捷菜单中添加几个菜单项,它可以使用户无须进入软件内部而直接在视窗中进行压缩/解压操作,十分方便用户操作,这无疑是一个较好的应用模型,它就是我们所说的Shell扩展技术.本文将以一个普通的源代码统计程序为例来说明怎样实现Shell扩展技术.下面是程序的运行效果图: 图一 示例代码运行效果图一 图二 示例代码运行效果图二 二.实现原理 为了在Windows的任何视窗中扩展文件或文件夹

ejb-有没有EJB JPA数据库持久层开发实践详解的源代码,麻烦给一份

问题描述 有没有EJB JPA数据库持久层开发实践详解的源代码,麻烦给一份 解决方案 书籍网上有好多下载的,源代码没有,建议你可以从这里,买一份,光盘里有源代码http://www.amazon.cn/dp/B001B8RVAW

如何编写一个可以输出自身源代码的程序

问题描述 如何编写一个可以输出自身源代码的程序 要求: 1.该程序不能从外部读取输入: 2.该程序输出的源码不能为空: 3.不能使用语言与shell的特性投机取巧: 在满足以上3点要求的情况下改程序可以对外输出自身的源代码 解决方案 怎样写一个输出自己源代码的程序一个难题: 怎样写一个输出自己源代码的程序?一个难题: 怎样写一个输出自己源代码的程序? 解决方案二: 自己加载类class;文件然后反编译成类,关键的反编译自己写不了吧?我的思路,抛砖引玉

CA收购开放源代码应用程序性能测试企业BlazeMeter

2016年9月20日--格林尼治标准时间20:49(东八区标准时间04:49) CA公司在星期二表示,该公司已经收购了BlazeMeter,这是一家专注于开放源代码应用程序性能测试的企业.这笔交易让CA能够更好地在其应用程序性能和DevOps产品组合同开放源代码的努力之间架起一道桥梁. 这笔交易将扩充CA的DevOps产品组合和应用程序交付工具.这笔交易将于今年年底完成,交易的条款未被披露. BlazeMeter的开放源代码工具将被用于更好地将CA的技术同开发人员连接在一起.BlazeMeter

俄罗斯方块源代码(winform程序,适合新人练手)

 参考了一个师兄的程序,后来问他,他说,程序也是参考的别人的,具体是谁忘记了. 在此向无名的开源英雄致意.同时把接力棒传下去 原代码下载地址:http://files.cnblogs.com/liulun/eluosi.rar 此程序可以配置按键,和方块的样式 用到了较多的数学知识,比如方块的翻转等. 具体代码就不多解释了.

《C语言及程序设计》实践参考——编程处理C源代码

返回:贺老师课程教学链接  实践要求 [项目5-编程处理C源代码]在CodeBlocks等IDE中都提供了代码格式整理的功能.我们可以编写程序,处理的数据就是用C写的源代码文件.C源文件是一种文本文件,可以通过程序进行操作.(1)读入一个C程序,判断其中是否只有一个main()函数,输出"暂时没有发现问题",或者"没有main()函数",或者"不能定义多个main()函数":提示1:简单处理,可以只比较判断"main()",考

C++实践参考:程序填空(范型程序设计)

[项目:程序填空]下面程序运行后,输出结果如下: 请填空将程序补充完整. #include <iostream> #include <vector> #include <algorithm> #include <functional> using namespace std; void Show(double); int main() { double arr1[5] = {2, 4, 8, 10, 16}; double arr2[5] = {1, 3,