【问题标题】:Preprocessor directive to create file names用于创建文件名的预处理器指令
【发布时间】:2012-10-27 03:47:47
【问题描述】:

我必须一个一个地打开文件才能用 C/C++ 阅读。文件名是in0、in1、in2、in3..... 我尝试使用预处理器指令来创建文件名。 我想要类似的东西。

for(int i=0;i<n;i++)
{
    string inp_file="/path/"+"in"+APPEND(i);  //to generate /path/in1 etc
    open(inp_file);
}

其中 APPEND 是一个宏。 自从

#define APP(i) i

可以产生价值

#define APP(i) #i

可以将标记转换为字符串。
我试图以多种方式将它们结合起来但失败了。 如何获得所需的结果,或者甚至可以通过宏获得这样的结果?

【问题讨论】:

  • 预处理器不能单独用于实现任何运行时功能。单独“用宏获得这样的结果”是不可能的。你所能做的就是将一些into-to-to-string转换函数包装到一个宏中,但是这样做并没有多大意义。

标签: c++ c c-preprocessor


【解决方案1】:

在您的情况下,变量i 不是编译时常量,因此不可能使用预处理器或模板专门化,因为在编译时该值根本不知道。您可以做的是将整数转换为字符串 - boost.lexical_cast 是最容易使用的解决方案之一:

for (int i = 0; i < n; ++i) {
    // Generate /path/in1 etc
    std::string inp_file = "/path/in"+ boost::lexical_cast<std::string>(i);
    open(inp_file);
}

如果你碰巧有一个支持 C++11 的编译器,你可以使用std::to_string()。例如:

for (int i = 0; i < n; ++i) {
    // Generate /path/in1 etc
    std::string inp_file = "/path/in" + std::to_string(i);
    open(inp_file);
}

希望对您有所帮助。祝你好运!

【讨论】:

    【解决方案2】:

    Vlad 回答的附录——如果由于某种原因你不能/不愿意使用 Boost,你可以使用标准 C++ 和 stringstream 类来完成你想要的:

    #include <sstream>
    
    void Foo() {
        for (int i = 0; i < n; ++i) {
            std::stringstream converter;
            converter << "/path/in" << i;
            open(converter.str());
        }
    }
    

    【讨论】:

    • Vlad Lazarenko 的回答中的上升次数反映了对相当标准的提升。但我想我会接受这个答案,因为我不需要更新我的任何库。(懒惰我!!)谢谢!!
    【解决方案3】:

    如果你没有使用 boost,试试这个:

    namespace StringUtils
    {
        // Converts any type which implements << to string (basic types are alright!)
        template<typename T>
        std::string StringUtils::toString(const T &t)
        {
           std::ostringstream oss;
           oss << t;
           return oss.str();
        }
    }
    

    这样使用:

    for(int i=0;i<n;i++)
    {
        string inp_file="/path/"+"in"+ StringUtils::toString(i);  //to generate /path/in1 etc
        open(inp_file);
    }
    

    【讨论】:

    • 这几乎就是 Boost 所做的。 +1
    【解决方案4】:

    只是对现有答案的补充,如果您使用更新的编译器和标准库,c++11 引入了std::to_string()。所以你可以这样写代码:

    for(int i = 0; i < n; i++) {
        string inp_file = "/path/in"+ std::to_string(i);
        open(inp_file);
    }
    

    【讨论】:

      【解决方案5】:

      C 解决方案是这样的:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      int main()
      {
        int n =4;
        char nstr[12];
        sprintf(nstr, "%d", n);
        int nlen = strlen( nstr );
      
      
        const char *fd = "/path/in";
        char buff[ strlen(fd) + nlen + 1 ];
      
        sprintf( buff, "%s%d", fd, n );
      
        /* for testing */
        printf( "%s\n", buff );
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-22
        • 1970-01-01
        • 2011-04-15
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        相关资源
        最近更新 更多