匯東網


头文件函数声明格式排版工具(九成品)

[編輯] [转简体]
|
作者:huidong | 分類:【編程】C/C++
[ 27 瀏覽 0 評論 6 贊 8 踩 ]

概要

正文

今天我在想怎样的函数声明好看……于是写了段代码自动排版,但是后来我觉得效果不太好,还是要灵活一点比较好。


这个工具能将一般的 C++ 头文件的函数声明排版成这样:

    // 图像缩放(基于 Win32 API,保留透明度信息)
    IMAGE
        ZoomImage_Win32_Alpha(
            IMAGE* pImg,
            int width,
            int height
        );

生成的 output.h 还需要放到 VS 里面进行格式对齐,因为我没有补 Tab 之类的。


但是后来我觉得又不太好看,算了。


代码写都写了,就留个纪念。现在基本功能可以了,但是还有一点小 Bug:一个参数的函数排版会失败,构造函数排版会失败,有时候很小一部分函数排版会失败,其余都可以。

#include <stdio.h>
#include <conio.h>
#include <string>
#include <vector>
#include <fstream>
#include <streambuf>
using namespace std;

// 获取文件内容
string GetFile(const char* filepath)
{
    ifstream t(filepath);
    string str((istreambuf_iterator<char>(t)), istreambuf_iterator<char>());
    t.close();

    if (str.size() <= 0)
    {
        printf("\n\nopen %s error.", filepath);
        _getch();
        exit(-1);
    }

    return str;
}

bool isSpace(char c)
{
    return c == ' ' || c == '\t';
}

bool isReturn(char c)
{
    return c == '\r' || c == '\n';
}

bool isBracket(char c)
{
    return c == '(';
}

bool isBackBracket(char c)
{
    return c == ')';
}

bool isSemicolon(char c)
{
    return c == ';';
}

bool StrCompare_Head(string res, string reference)
{
    for (size_t i = 0; i < reference.size() && i < res.size(); i++)
    {
        if (res[i] != reference[i])
        {
            return false;
        }
    }
    return true;
}

void SkipSpace(string res, size_t& index)
{
    for (; index < res.size(); index++)
    {
        if (!isSpace(res[index]))
        {
            return;
        }
    }
}

void SkipReturn(string res, size_t& index)
{
    for (; index < res.size(); index++)
    {
        if (!isReturn(res[index]))
        {
            return;
        }
    }
}

void SkipComment(string res, size_t& index)
{
    while (StrCompare_Head(&res[index], "//"))
    {
        for (; index < res.size(); index++)
        {
            if (isReturn(res[index]))
            {
                SkipReturn(res, index);
                break;
            }
        }
    }
}

// 返回跳过的字符长度
size_t SkipWord(string res, size_t& index)
{
    size_t sum = 0;
    for (; index < res.size(); index++)
    {
        if (isReturn(res[index]) || isSpace(res[index]) || isBracket(res[index]))
        {
            SkipReturn(res, index);
            SkipSpace(res, index);
            return sum;
        }
        else
        {
            sum++;
        }
    }
    return sum;
}

// 遇到第一个无匹配的反括号时返回
void SkipBrackets(string res, size_t& index)
{
    for (int num = 0; index < res.size(); index++)
    {
        if (isBracket(res[index]))
        {
            num++;
        }
        else if (isBackBracket(res[index]))
        {
            num--;
        }

        // 不成对的反括号
        if (num < 0)
        {
            index++;
            return;
        }
    }
}

bool isFunction(string res, size_t& index)
{
    SkipSpace(res, index);
    size_t begin = index;
    if (SkipWord(res, index) && SkipWord(res, index))
    {
        if (isBracket(res[index]))
        {
            index++;
            SkipBrackets(res, index);
            if (isSemicolon(res[index]))
            {
                index = begin;
                return true;
            }
        }
    }
    return false;
}

void NewLine(string& res, size_t& index)
{
    res.insert(res.begin() + index, '\n');
    index++;
}

void ProcFunc(string& res, size_t& index)
{
    SkipWord(res, index);
    if (!isReturn(res[index]))
    {
        NewLine(res, index);
    }
    SkipWord(res, index);
    index++;    // 跳过函数括号

    // 函数无参数
    if (isBackBracket(res[index]))
    {
        index++;
        SkipReturn(res, index);
        return;
    }

    for (; index < res.size(); index++)
    {
        if (!isReturn(res[index]))
        {
            NewLine(res, index);
        }

        for (; index < res.size(); index++)
        {
            // 参数,继续换行
            if (res[index] == ',')
            {
                break;
            }
            // 函数声明结束
            if (StrCompare_Head(&res[index], ");"))
            {
                index--;
                // 往前找
                size_t i = 0;
                for (; index > 0; index--, i++)
                {
                    // 已有换行,无需再换
                    if (isReturn(res[index]))
                    {
                        break;
                    }
                    // 若存在文本,则换行
                    else if (!isSpace(res[index]))
                    {
                        index++;
                        NewLine(res, index);
                        break;
                    }
                }
                index += i + 2;    // 跳过反括号
                SkipReturn(res, index);
                return;
            }
        }
    }
}

void Proc(string& res)
{
    for (size_t index = 0; index < res.size(); index++)
    {
        SkipReturn(res, index);
        SkipSpace(res, index);
        SkipComment(res, index);
        if (isFunction(res, index))
        {
            ProcFunc(res, index);
        }

        // 不是函数则进入下一行
        else
        {
            for (; index < res.size(); index++)
            {
                if (isReturn(res[index]))
                {
                    break;
                }
            }
        }
    }
}

int main()
{
    char buf[1024] = { 0 };
    printf("Type your header file path:\n");
    string strCode = GetFile(gets_s(buf));
    Proc(strCode);

    ofstream out(L"output.h");
    out.write(strCode.c_str(), strCode.size());
    out.close();

    printf("%s\n", strCode.c_str());

    _getch();

    return 0;
}


[ 6] [ 8]


 評論區  0 條評論

+ 添加評論