首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言刪除 .c 文件註釋:動態庫實現與 MISRA C 合規要點

     編輯:程式設計綜合問答

需求拆解

  1. 讀取 .c 文件,移除所有註釋(// 單行、/* */ 多行),寫入新文件。
  2. 核心邏輯封裝為動態鏈接庫(.so/.dll)。
  3. 單元測試覆蓋邊界情況;通過 MISRA C 檢查;符合編碼規範。

核心算法:狀態機

typedef enum { NORMAL, IN_SINGLE_LINE, IN_MULTI_LINE, IN_STRING, IN_CHAR } State;

void strip_comments(FILE *in, FILE *out) {
    State state = NORMAL;
    int c, prev = 0;
    while ((c = fgetc(in)) != EOF) {
        switch (state) {
            case NORMAL:
                if (prev == '/' && c == '/') state = IN_SINGLE_LINE;
                else if (prev == '/' && c == '*') state = IN_MULTI_LINE;
                else {
                    if (prev) fputc(prev, out);
                    if (c == '"') state = IN_STRING;
                    else if (c == '\'') state = IN_CHAR;
                }
                break;
            case IN_SINGLE_LINE:
                if (c == '\n') { state = NORMAL; fputc(c, out); }
                break;
            case IN_MULTI_LINE:
                if (prev == '*' && c == '/') state = NORMAL;
                break;
            case IN_STRING:
                fputc(prev, out);
                if (c == '"' && prev != '\\') state = NORMAL;
                break;
            case IN_CHAR:
                fputc(prev, out);
                if (c == '\'' && prev != '\\') state = NORMAL;
                break;
        }
        prev = c;
    }
    if (prev && state == NORMAL) fputc(prev, out);
}

關鍵邊界處理

  • 字符串/字符常量內的 // /* 不視為註釋。
  • 轉義字符 \\\" \\' 不結束字符串/字符常量。
  • 多行註釋嵌套(C 標準不支持嵌套,遇首個 */ 結束)。
  • 行綴續符 \\ 導致單行註釋延續。

動態庫導出接口

// strip.h
#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __attribute__((visibility("default")))
#endif

EXPORT int strip_comments_file(const char *in_path, const char *out_path);

MISRA C 合規要點

  • Rule 8.1:函數原型必須聲明(static 內部函數除外)。
  • Rule 10.3:隱式類型轉換需顯式轉換。
  • Rule 17.4:指針算術僅用於數組索引。
  • Rule 21.1:malloc/free 成對使用,檢查返回值。
  • 禁用 gets、sprintf 等不安全函數,改用 fgets、snprintf。

單元測試覆蓋

用例輸入片段期望輸出
單行註釋int a; // commentint a;
多行註釋/* comment */ int b; int b;
字符串內類註釋char *s = "// not comment";保持原樣
字符常量char c = '/';保持原樣
行綴續// comment \\\n continued整行移除
嵌套註釋/* outer /* inner */ end */ end */(按標準)

構建與集成

# CMakeLists.txt
add_library(strip_comments SHARED strip.c)
target_include_directories(strip_comments PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# 啟用 MISRA 檢查(需外部工具如 cppcheck --enable=misra 或 PC-lint)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved