【C语言】C代码注释转换

C语言注释转换是C语言内比较小的一个课题,这个课题的主要思想是需要考虑到可能出现的情况,然后转换为我们能用程序语言描述的情形。

一般可以分为7种情形:
1.一般情况
/* int i = 0; */

2.换行问题
/* int i = 0; */int j = 0;

3.匹配问题
/int i = 0;/*xxxxx/

4.多行注释问题
/*
int i=0;
int j = 0;
int k = 0;
*/int k = 0;

5.连续注释问题
/ * * / / * */

6.连续的 **/问题
/* * */

7.C++注释问题
// /* xxxxxxxxxxxx */

在这里每一种情形都可以分步讨论,先判断第一个读取的字符,如果是‘/’ ,就可以考虑是否会出现上面说的情形;如果不是,直接读取然后写入另一个文件中。如果是‘/’,接下来继续判断下一个可能会出现的情况,出现‘*’就跳到C语言转换的函数;如果是‘/’,那么就跳到C++语言转换的函数;如果是其他字符,直接读取然后存入文件中。

//头文件声明部分

#ifndef __COMMENTCONVERT_H__
#define __COMMENTCONVERT_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

enum STATE   //定义4个状态
{
    NUL_STATE,    //无状态,也就是正常状态
    C_STATE,      //C语言状态
    CPP_STATE,    //C++状态
    END_STATE     //文件读取完成
};

void DoConvert(FILE *pfIn,FILE *pfOut);
void DoNULLState(FILE *pfIn,FILE *pfOut,enum STATE *psta);
void DoCState(FILE *pfIn,FILE *pfOut,enum STATE *psta);
void DoCppState(FILE *pfIn,FILE *pfOut,enum STATE *psta);

#endif
//主要函数部分
#include"CommentConvert.h"

void DoConvert(FILE *pfIn,FILE *pfOut)  //判断可能出现的情形
{
    enum STATE state=NUL_STATE;    //开始的时候设置为无状态
    while(state!=END_STATE)        //用while循环控制整个程序的执行
    {
        switch(state)
        {
        case NUL_STATE:
            {
                DoNULLState(pfIn,pfOut,&state);
                break;
            }

        case C_STATE:
            {
                DoCState(pfIn,pfOut,&state);
                break;
            }

        case CPP_STATE:
            {
                DoCppState(pfIn,pfOut,&state);
                break;
            }

        case END_STATE:
            break;

        default:
            break;
        }
    }
}

void DoNULLState(FILE *pfIn,FILE *pfOut,enum STATE *psta) //无状态
{
    char first=0;
    char second=0;
    first=fgetc(pfIn);
    switch(first)         //判断第一个读取的字符是什么
    {
        case '/':
        {
            second=fgetc(pfIn);
            switch(second)
            {
            case '*':      //1.一般情况 
                {
                    fputc('/',pfOut);
                    fputc('/',pfOut);
                    *psta=C_STATE;
                    break;
                }

            case '/':     //7.C++注释问题  

                {
                    fputc(first,pfOut);
                    fputc(second,pfOut); 
                    *psta=CPP_STATE;
                    break;
                }

            default:
                {
                    fputc(first,pfOut);
                    fputc(second,pfOut);
                    break;
                }
            }
            break;
        }

       case EOF:   //文件结束标志
           {
               fputc(first,pfOut);
               *psta=END_STATE;
               break;
           }

       default:    
           {
               fputc(first,pfOut);
               break;
           }
    }
}

void DoCState(FILE *pfIn,FILE *pfOut,enum STATE *psta) //C语言状态
{
    char first=0;
    char second=0;
    char third=0;
    first=fgetc(pfIn);
    switch(first)       //3.匹配问题
    {
    case '*':
        {
            second=fgetc(pfIn);
            switch(second)
            {
            case '/':
                {
                    third=fgetc(pfIn);
                    *psta=NUL_STATE;
                    if(third=='\n')         //2.换行问题
                            fputc('\n',pfOut);

                    else
                    { 
                       fputc('\n',pfOut);
                       ungetc(third,pfIn);
                    }
                    break;
                }

            case '*':      // 6.连续的**/问题  
                {
                    fputc(first,pfOut);
                    ungetc(second,pfIn);
                    break;
                }

            default:
                {
                    fputc(first,pfOut);
                    fputc(second,pfOut);
                    break;
                }
            }
            break;
        }

    case '\n':              //4.多行注释问题
        {
            fputc('\n',pfOut);
            fputc('/',pfOut);
            fputc('/',pfOut);
            *psta=C_STATE;
            break;
        }

    default:
        {
            fputc(first,pfOut);
            break;
        }
    }
}

void DoCppState(FILE *pfIn,FILE *pfOut,enum STATE *psta) //C++状态
{
    char first=0;
    char second=0;
    first=fgetc(pfIn);
    switch(first)
    {
    case '\n':
        {
            fputc(first,pfOut);
            *psta=NUL_STATE;
            break;
        }

     case EOF:
        {
            *state = END_STATE;
            break;
        }       

    default:
        {
             fputc(first,pfOut);
             break;
        }
    }
}
//测试函数
#include<stdio.h>
#include<stdlib.h>
#include"CommentConvert.h"

int main()
{
    FILE *pfIn;
    FILE *pfOut;
    pfIn=fopen("input.c","r");

    if(pfIn==NULL)
    {
        perror("open file failed");
        exit(EXIT_FAILURE);
    }

    pfOut=fopen("output.c","w");

    if(pfOut==NULL)
    {
        fclose(pfIn);
        perror("open  failed\n");
        exit(EXIT_FAILURE);
    }

    DoConvert(pfIn, pfOut);
    fclose(pfIn);
    pfIn=NULL;
    fclose(pfOut);
    pfOut=NULL;
    system("pause");
    return 0;
}

结果如下:
这里写图片描述

总结:
1.本人在写过程中,第一个出现的问题是提示是“open file failed”。反复检查看好几遍,很确定自己建立了这两个文件。最后的最后才发现文件名多了一个字母,满屏的尴尬脸啊!

2.文件正常执行后,发现在换行多行注释的过程中int的i老丢,调试好几次后发现是在写C语言状态的时候没有考虑清楚应该给缓存区放第几个字符。一定要记住在”ungetc(third,pfIn)“中,我们已经判断到第三个字符了,所以放的也是第三个!读取哪个字符就要对哪个字符负责,千万不能“始乱终弃”!

3.有问题一定要去调试!调试!在调试前可以通过对错误现象的分析,初步估计一下问题可能出现在哪里,然后一步一步调试,直到完全找到错误出现的地方。

好的,我知道了。以下是哈希算法MD5的C语言代码注释: ```C #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) // 将输入字符串转换为二进制表示,并进行填充 // 对于较短的输入,填充到长度为 448 mod 512 // 然后在末尾添加一个长度为 64 位的二进制数,表示输入长度 uint8_t *md5(const char *message) { // 消息填充,以及长度记录 size_t initial_len = strlen(message); uint8_t *msg = calloc(initial_len + 64, 1); memcpy(msg, message, initial_len); msg[initial_len] = 128; uint64_t bits_len = 8 * initial_len; memcpy(msg + initial_len + 56, &bits_len, 8); // 初始化 MD 缓冲区 uint32_t h0 = 0x67452301; uint32_t h1 = 0xEFCDAB89; uint32_t h2 = 0x98BADCFE; uint32_t h3 = 0x10325476; // 循环压缩每个 512 位的消息块 for (int i = 0; i < initial_len + 64; i += 64) { uint32_t *w = (uint32_t *)(msg + i); uint32_t a = h0; uint32_t b = h1; uint32_t c = h2; uint32_t d = h3; // 进行 64 次操作 for (int j = 0; j < 64; ++j) { uint32_t f, g; if (j < 16) { f = (b & c) | ((~b) & d); g = j; } else if (j < 32) { f = (d & b) | ((~d) & c); g = (5 * j + 1) % 16; } else if (j < 48) { f = b ^ c ^ d; g = (3 * j + 5) % 16; } else { f = c ^ (b | (~d)); g = (7 * j) % 16; } uint32_t temp = d; d = c; c = b; b += LEFTROTATE((a + f + k[j] + w[g]), r[j]); a = temp; } h0 += a; h1 += b; h2 += c; h3 += d; } // 将缓冲区拼接为最终的哈希值 uint8_t *result = calloc(16, 1); memcpy(result, &h0, 4); memcpy(result + 4, &h1, 4); memcpy(result + 8, &h2, 4); memcpy(result + 12, &h3, 4); free(msg); return result; } int main() { char *message = "hello world"; uint8_t *hash = md5(message); for (int i = 0; i < 16; ++i) { printf("%02x", hash[i]); } printf("\n"); free(hash); return 0; } ``` 以上是哈希算法MD5的C语言实现代码,并进行了注释,希望能够帮助你。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值