【问题标题】:Print name of the function that the variables belong to in C++在 C++ 中打印变量所属函数的名称
【发布时间】:2021-05-02 11:02:23
【问题描述】:

我在尝试解决这个问题时遇到了很多麻烦。我必须读取一个具有三个函数(add、sub 和 main)的 .c 文件,并且我想在控制台上打印它们的变量名称,并在括号中加上函数名称。我尝试在我的结构中实现一个字符串 function_name 来存储函数的值,但我不知道如何在我的变量旁边打印它,直到我点击另一个函数。任何帮助或建议将不胜感激。

例如:

来自这个 .c 文本

int add ( int a , int b )
{
    return a + b ;
}

我想得到这个:

add, line 1, function, int, referenced 2
a (add), line 1, variable, int, referenced 1 
b (add), line 1, variable, int, referenced 1

但我明白了:

add(add), line 1, function, int, referenced 16
a, line 1, variable, int, referenced 15
b, line 1, variable, int, referenced 15

到目前为止,我的代码如下所示。

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>

using namespace std;

struct identifier
{
    string id_name; 
    string function_name;
    int id_count; 
    string id_function;
    string id_type;
    int id_ref;

};

int main(int argc, char** argv)
{
    
    
    if (argc < 2)
    {
        cout << "ERROR: There is no file selected." << endl;
    }
    
    ifstream file(argv[1]);
    string line;
    string token;
    vector<identifier> id_list;

    int line_counter = 0;
    int num_functions = 0;
    int num_variables = 0;
    int num_if = 0;
    int num_for = 0;
    int num_while = 0;
    

    while (getline(file, line))
    {
        stringstream stream(line);

        line_counter++;

        while (stream >> token)
        {
           bool found = false;
            for (auto& v : id_list)
            {
                if (v.id_name == token)
                {
                    //We have seen the word so add one to its count
                    v.id_ref++;
                    found = true;
                    break;
                }
            }
           if (token == "int" || token == "int*")
            {
                string star = token;
                identifier intI;

                stream >> token;
                string name = token;
               
                intI.id_name = name;
                intI.id_count = line_counter;
                intI.id_type = "int";
               
                stream >> token; //Get the next token
                if (token == "(")
                {
                    //We have a function
                    intI.id_function = "function";
                    
                    if (intI.id_name != "main")
                    {
                        intI.function_name = "(" + name + ")";
                    }
                    
                    num_functions++;
                }
                else
                {
                    //We have a variable
                    intI.id_function = "variable";

                    if (star == "int*")
                    {
                        intI.id_type = "int*";
                    }

                    num_variables++;
                }
                 id_list.push_back(intI);
            }
        }
    file.close();
    //Print the words and their counts
   
    for (auto& v : id_list)
    {
      cout << v.id_name << v.function_name << ", line " << v.id_count << ", " << v.id_function << ", " << v.id_type << ", referenced " << v.id_ref << endl;
    }

    return 0;

【问题讨论】:

  • 我可能只是瞎了眼,但我没有看到 id_ref 在任何地方被初始化。您还需要跟踪您当前所在的函数,以便能够将其与函数内部的变量一起存储。
  • 我编辑了,忘记添加那段代码了,谢谢指出。而且,我该怎么做?如何存储我所在的功能?使用 while 循环保持它直到找到标记“}”?

标签: c++ scope token


【解决方案1】:

我可以看到您现在正在增加 id_ref,但它仍未初始化,因此您有未定义的行为。最简单的方法是在struct 中定义的= 0;

至于你的函数,假设这里没有嵌套函数,那么你可以只使用一个变量来跟踪它。

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>

struct identifier {
    std::string id_name;
    std::string function_name;
    int id_count;
    std::string id_function;
    std::string id_type;
    int id_ref = 0; // if not initialized, then you will get seemingly random numbers

};

int main( int argc, char **argv ) {


    if ( argc < 2 )     {
        std::cout << "ERROR: There is no file selected." << std::endl;
        return 1; // quit early
    }

    std::ifstream file( argv[1] );
    std::string line;
    std::string token;
    std::vector<identifier> id_list;

    int line_counter = 0;
    int num_functions = 0;
    int num_variables = 0;
    int num_if = 0;
    int num_for = 0;
    int num_while = 0;

    std::string current_function; // keep track of the function


    while ( std::getline( file, line ) ) {
        std::stringstream stream( line );

        line_counter++;

        while ( stream >> token ) {
            bool found = false;
            for ( auto &v : id_list ) {
                if ( v.id_name == token ) {
                    //We have seen the word so add one to its count
                    v.id_ref++;
                    found = true;
                    break;
                }
            }
            if ( token == "int" || token == "int*" ) {
                std::string star = token;
                identifier intI;

                stream >> token;
                std::string name = token;

                intI.id_name = name;
                intI.id_count = line_counter;
                intI.id_type = "int";

                stream >> token; //Get the next token
                if ( token == "(" ) {
                    //We have a function
                    intI.id_function = "function";

                    if ( intI.id_name != "main" ) {
                        current_function = name; // update the current function name

                    }

                    num_functions++;
                } else {
                    intI.function_name = "(" + current_function + ")"; // add the function name to the variable name
                    //We have a variable
                    intI.id_function = "variable";

                    if ( star == "int*" ) {
                        intI.id_type = "int*";
                    }

                    num_variables++;
                }
                id_list.push_back( intI );
            }
        }
    }
    //file.close();
    //Print the words and their counts

    for ( const auto &v : id_list ) {
        std::cout << v.id_name << v.function_name << ", line " << v.id_count << ", " << v.id_function << ", " << v.id_type << ", referenced " << v.id_ref << std::endl;
    }

    return 0;
}

还有一些recommended reading on using namespace std

修改为使用字符串而不是参数的工作示例:https://godbolt.org/z/jKqqrhce6

【讨论】:

  • 非常感谢您的帮助,它完美无缺!加上所有阅读建议和编译器链接。我去看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 2019-09-08
相关资源
最近更新 更多