开发者

Preprocessor directive to create file names

开发者 https://www.devze.com 2023-04-02 08:36 出处:网络
I have to open files one by one for reading in C/C++. The name of the files are in0, in1, in2, in3.....

I have to open files one by one for reading in C/C++. The name of the files are in0, in1, in2, in3..... I tried to use preprocessor directive to create file names. i want something like.

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

where APPEND is a MACRO. Since

#define APP(i) i

can generate the value

#define APP(i) #i

can convert a token to string.

I am trying to combine th开发者_JAVA百科em both in many ways but failed. How to get the desired result or is it even possible to get the such a result with macro?


In your case, the variable i is not a compile-time constant and so it is impossible to use pre-processor or template specialization because the value is simply not known at a time of compilation. What you can do is convert integer into string - boost.lexical_cast is one of the easiest to use solutions:

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);
}

If you happen to have a compiler with C++11 support, you could use std::to_string(). For example:

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

Hope it helps. Good Luck!


Addendum to Vlad's answer -- if for some reason you're not able/willing to use Boost, you can accomplish what you want using standard C++ with the stringstream class:

#include <sstream>

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


If you're not using boost, try this:

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();
    }
}

Use it this way:

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


Just an addition to the existing answers which are all great, if you are using a newer compiler and standard library, c++11 introduces std::to_string(). So you can write code like this:

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


The C solution is this :

#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 );
}
0

精彩评论

暂无评论...
验证码 换一张
取 消