You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C/C++代码无法正确识别变量与预处理器,求修正方案

问题:C++变量与预处理器识别程序修正

任务要求

  • 编写名为ID.cpp的C++程序,完成以下操作:
    a. 读取名为“program.cpp”的文件;
    b. 识别并统计其中唯一的变量名与预处理器名,输出结果。

现有问题

编写的代码无法正确识别变量与预处理器,需进行修正。

现有代码

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
#include <cctype>

using namespace std;

int main()
{
    string filename;
    cout << "Enter filename: ";
    cin >> filename;
    
    ifstream infile(filename.c_str());
    if (!infile)
    {
        cerr << "Error: could not open file " << filename << endl;
        return 1;
    }
    
    map<string, int> variables;
    map<string, int> preprocessors;
    
    string line;
    while (getline(infile, line))
    {
        string::iterator it = line.begin();
        while (it != line.end())
        {
            if (*it == '#')
            {
                string preprocessor;
                ++it;
                while (it != line.end() && !isspace(*it))
                {
                    preprocessor += *it;
                    ++it;
                }
                ++preprocessors[preprocessor];
            }
            else if (isalpha(*it) || *it == '_')
            {
                string variable;
                while (it != line.end() && (isalnum(*it) || *it == '_'))
                {
                    variable += *it;
                    ++it;
                }
                ++variables[variable];
            }
            else
            {
                ++it;
            }
        }
    }
    
    cout << "Variables:" << endl;
    for (map<string, int>::iterator it = variables.begin(); it != variables.end(); ++it)
    {
        cout << it->first << ": " << it->second << endl;
    }
    
    cout << "Preprocessors:" << endl;
    for (map<string, int>::iterator it = preprocessors.begin(); it != preprocessors.end(); ++it)
    {
        cout << it->first << ": " << it->second << endl;
    }
    
    return 0;
}

预期输出

Variable-1: a
Variable-2: b
Variable-3: c
Variable-4: d
Variable-5: e
Total number of the variables: 5
Preprocessor-1: include
Preprocessor-2: define
Total number of preprocessor: 2

修正方案

原代码核心问题

  1. 未排除C++关键字:把int、string这类关键字误统计为变量。
  2. 未处理注释与字符串:注释、字符串中的标识符会被错误识别。
  3. 预处理器识别逻辑粗糙:会把#后所有非空白字符都当成指令,且未跳过注释/字符串中的#。
  4. 输出格式不符预期:原输出是“变量名: 出现次数”,但要求按序号列出唯一标识符并统计总数。
  5. 未满足固定文件名要求:任务要求读取program.cpp,但原代码让用户输入文件名。

修正后的代码

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <unordered_set>
#include <cctype>

using namespace std;

// C++关键字集合,用于排除非变量标识符
const unordered_set<string> keywords = {
    "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor",
    "bool", "break", "case", "catch", "char", "char8_t", "char16_t", "char32_t",
    "class", "compl", "concept", "const", "consteval", "constexpr", "constinit",
    "const_cast", "continue", "co_await", "co_return", "co_yield", "decltype",
    "default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit",
    "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline",
    "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq",
    "nullptr", "operator", "or", "or_eq", "private", "protected", "public",
    "reflexpr", "register", "reinterpret_cast", "requires", "return", "short",
    "signed", "sizeof", "static", "static_assert", "static_cast", "struct",
    "switch", "template", "this", "thread_local", "throw", "true", "try", "typedef",
    "typeid", "typename", "union", "unsigned", "using", "virtual", "void",
    "volatile", "wchar_t", "while", "xor", "xor_eq"
};

int main()
{
    const string filename = "program.cpp";
    ifstream infile(filename);
    if (!infile)
    {
        cerr << "Error: could not open file " << filename << endl;
        return 1;
    }

    map<string, int> variables;
    map<string, int> preprocessors;

    string line;
    bool in_multi_comment = false; // 标记是否处于多行注释

    while (getline(infile, line))
    {
        string::iterator it = line.begin();
        bool in_single_comment = false; // 标记是否处于单行注释
        bool in_string = false; // 标记是否处于字符串
        char string_quote = '\0'; // 记录字符串的引号类型('或")

        while (it != line.end())
        {
            // 处理多行注释
            if (in_multi_comment)
            {
                if (*it == '*' && next(it) != line.end() && *(next(it)) == '/')
                {
                    in_multi_comment = false;
                    advance(it, 2);
                }
                else
                {
                    ++it;
                }
                continue;
            }

            // 单行注释直接跳至行尾
            if (in_single_comment)
            {
                break;
            }

            // 处理字符串内容
            if (in_string)
            {
                if (*it == string_quote && prev(it) != line.begin() && *(prev(it)) != '\\')
                {
                    in_string = false;
                }
                ++it;
                continue;
            }

            // 识别预处理器指令
            if (*it == '#')
            {
                ++it;
                // 跳过#后的空白字符
                while (it != line.end() && isspace(*it))
                {
                    ++it;
                }
                string preprocessor;
                while (it != line.end() && !isspace(*it))
                {
                    preprocessor += *it;
                    ++it;
                }
                if (!preprocessor.empty())
                {
                    ++preprocessors[preprocessor];
                }
                continue;
            }

            // 识别多行注释开始
            if (*it == '/' && next(it) != line.end() && *(next(it)) == '*')
            {
                in_multi_comment = true;
                advance(it, 2);
                continue;
            }

            // 识别单行注释开始
            if (*it == '/' && next(it) != line.end() && *(next(it)) == '/')
            {
                in_single_comment = true;
                advance(it, 2);
                continue;
            }

            // 识别字符串开始
            if (*it == '"' || *it == '\'')
            {
                in_string = true;
                string_quote = *it;
                ++it;
                continue;
            }

            // 识别变量标识符
            if (isalpha(*it) || *it == '_')
            {
                string identifier;
                while (it != line.end() && (isalnum(*it) || *it == '_'))
                {
                    identifier += *it;
                    ++it;
                }
                // 排除关键字,只统计变量
                if (keywords.find(identifier) == keywords.end())
                {
                    ++variables[identifier];
                }
            }
            else
            {
                ++it;
            }
        }
    }

    // 按预期格式输出变量
    cout << "Variables:" << endl;
    int var_idx = 1;
    for (const auto& pair : variables)
    {
        cout << "Variable-" << var_idx << ": " << pair.first << endl;
        var_idx++;
    }
    cout << "Total number of the variables: " << variables.size() << endl;

    // 按预期格式输出预处理器
    cout << "\nPreprocessors:" << endl;
    int pre_idx = 1;
    for (const auto& pair : preprocessors)
    {
        cout << "Preprocessor-" << pre_idx << ": " << pair.first << endl;
        pre_idx++;
    }
    cout << "Total number of preprocessor: " << preprocessors.size() << endl;

    return 0;
}

修正说明

  • 新增关键字集合,排除int、string等非变量标识符。
  • 加入注释、字符串识别逻辑,避免误统计这些区域内的内容。
  • 优化预处理器识别,仅提取#后的有效指令,跳过无关空白字符。
  • 调整输出格式,完全匹配预期的序号式列表+总数统计。
  • 固定读取program.cpp,符合任务要求。

内容的提问来源于stack exchange,提问作者sajid mahbub

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 10:57:36