How to replace a string in #include define by using #DEFINE

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • yanjie111
    New Member
    • Apr 2007
    • 14

    How to replace a string in #include define by using #DEFINE

    The original #include string like this:

    #include "my_path1\Inclu des\types.h"

    I want to change like this

    #DEFINE MY_PATH my_path1

    #include "MY_PATH\includ e\types.h"

    This can not be compiled. Is there a $() or other symbol needed?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    The \ is an escape sequence character, like \n. The character after the \ is a code. To have an actual backslash, you must use \\. In this case the character after the \ is a \ which is a code for the character \ so the end result is one \.

    Your path should be:
    Code:
    #include "my_path1\\Includes\types.h"

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      Oops. I forgot the second \. Let me try again:

      Code:
      #include "my_path1\\Includes\\types.h"

      Comment

      • AdrianH
        Recognized Expert Top Contributor
        • Feb 2007
        • 1251

        #4
        Originally posted by yanjie111
        The original #include string like this:

        #include "my_path1\Inclu des\types.h"

        I want to change like this

        #DEFINE MY_PATH my_path1

        #include "MY_PATH\includ e\types.h"

        This can not be compiled. Is there a $() or other symbol needed?
        So your question is that you wish to use a symbol for the start of your include path?

        If you don't want to add the -I switch to your compile line, you can do what you are asking like this:

        #define MY_PATH "my_path1/"
        #include MY_PATH "include/types.h"

        The way the C/C++ compiler deals with strings is that if there are two or more consecutive strings separated by only whitespace or nothing, then it is to concatenate the strings together.

        BTW. you should use the '/' not the '\' in your strings for includes, it should work for all compilers. I'm not positive if '\' is standard and even if it is, you would have to double them up like weakness stated.


        Adrian

        Comment

        • yanjie111
          New Member
          • Apr 2007
          • 14

          #5
          I did not explain clearly before.
          My problem is I want to replace a string in the #include string by prepressor MACRO definition.

          I have the same file name types.h in different directories. They have different content because different build will use them.
          In one build, I want include
          #include "my_path1\types .h"

          In another build, I want include
          #include "my_path2\types .h"

          I want to use a macro definition to switch between them during compiling process.

          #define PATH_NAME my_path1
          #include "PATH_NAME\type s.h"

          Can the compiler change it to
          #include "my_path1\types .h"
          automatically?

          If I change to
          #define PATH_NAME my_path2
          #include "PATH_NAME\type s.h"

          Can the compiler change it to
          #include "my_path2\types .h"
          automatically?


          Can preprocessor change preprocessor?
          That's my question.

          Comment

          • AdrianH
            Recognized Expert Top Contributor
            • Feb 2007
            • 1251

            #6
            Originally posted by yanjie111
            I did not explain clearly before.
            My problem is I want to replace a string in the #include string by prepressor MACRO definition.

            I have the same file name types.h in different directories. They have different content because different build will use them.
            In one build, I want include
            #include "my_path1\types .h"

            In another build, I want include
            #include "my_path2\types .h"

            I want to use a macro definition to switch between them during compiling process.

            #define PATH_NAME my_path1
            #include "PATH_NAME\type s.h"

            Can the compiler change it to
            #include "my_path1\types .h"
            automatically?

            If I change to
            #define PATH_NAME my_path2
            #include "PATH_NAME\type s.h"

            Can the compiler change it to
            #include "my_path2\types .h"
            automatically?


            Can preprocessor change preprocessor?
            That's my question.
            Yes, just like I suggested in my last post.

            Alternatively, you can use a #if/#else/#endif to manipulate the include like

            Code:
            #if USE_PATH == 1
            # include "my_path1/types.h"
            #else
            # include "my_path2/types.h"
            #endif
            Again, use slashes (/) not backslashes (\) or you may get into trouble.


            Adrian

            Comment

            • yanjie111
              New Member
              • Apr 2007
              • 14

              #7
              The first way you suggested does not work. I changed the \ to /.
              If I use
              #define PATH_VALUE "mypath1/types.h"
              #include PATH_VALUE
              it works. But I can not combine two strings like this
              #define PATH_VALUE "mypath1"
              #include PATH_VALUE "/types.h"
              The compile error is:
              fatal error C1083: Cannot open include file: "mypath1"
              It can not see the second string and combine it.

              The second way you suggested is OK. Because a lot of files have the #include line and there are too much different path name. That means in every source code I must add a very long
              #if
              #elif
              #elif
              #elif
              #elif
              #endif
              Is there a better way to do that?
              I hope the first method works. What's the problem?
              If that works, I don't need to change any source code. Only create one makefile for each case.

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                I'm getting a better picture here.

                Instead of this:

                Code:
                #include "my_path1\types.h"
                
                In another build, I want include
                #include "my_path2\types.h"
                How about:
                Code:
                #include <types.h>
                or
                #include "types.h"
                Using <> causes the preprocessor to search a pre-defined path (called a "standard place". Just set the path to your header in the project settings of your IDE.

                Using " " causes the proprocessor to look for the header in the PWD (present working directory) which is the folder with the project file for Visual Studio. If the header is not there, the search reverts to a standard place as though you had used <> on the include.

                Comment

                • AdrianH
                  Recognized Expert Top Contributor
                  • Feb 2007
                  • 1251

                  #9
                  Originally posted by yanjie111
                  The first way you suggested does not work. I changed the \ to /.
                  If I use
                  #define PATH_VALUE "mypath1/types.h"
                  #include PATH_VALUE
                  it works. But I can not combine two strings like this
                  #define PATH_VALUE "mypath1"
                  #include PATH_VALUE "/types.h"
                  The compile error is:
                  fatal error C1083: Cannot open include file: "mypath1"
                  It can not see the second string and combine it.

                  The second way you suggested is OK. Because a lot of files have the #include line and there are too much different path name. That means in every source code I must add a very long
                  #if
                  #elif
                  #elif
                  #elif
                  #elif
                  #endif
                  Is there a better way to do that?
                  I hope the first method works. What's the problem?
                  If that works, I don't need to change any source code. Only create one makefile for each case.
                  Doesn't work? What compiler are you using?

                  If you want to, you can something like this:
                  Code:
                  #define STRINGIZE(x) STRINGIZE_A(x)
                  #define STRINGIZE_A(x) #x
                  #define MY_PATH() my_path1
                  #include STRINGIZE(MY_PATH()/types.h)
                  I am almost positive that it will work properly.

                  Alternatively, use an include indirection. Do this by making a header file with the #if/#elif/#endif you described and then include that header, which will then include the correct one. That will definitely work properly.

                  Hope that helps,


                  Adrian

                  Comment

                  • Banfa
                    Recognized Expert Expert
                    • Feb 2006
                    • 9067

                    #10
                    Originally posted by AdrianH
                    Doesn't work? What compiler are you using?
                    String concatenation is part of the compiler, at the point that yanjie111 is talking about the preprocessor is working. The preprocessor does not do string concatenation in that way.

                    The preprocessor does have a string concatenation operator but I have never tried using it in a #include statement.

                    All in all yanjie111 I agree with weaknessforcats , you are better off just putting your #include in normally without any path and then modifying the path using compiler switches for the different builds.

                    Comment

                    • AdrianH
                      Recognized Expert Top Contributor
                      • Feb 2007
                      • 1251

                      #11
                      Originally posted by Banfa
                      String concatenation is part of the compiler, at the point that yanjie111 is talking about the preprocessor is working. The preprocessor does not do string concatenation in that way.

                      The preprocessor does have a string concatenation operator but I have never tried using it in a #include statement.

                      All in all yanjie111 I agree with weaknessforcats , you are better off just putting your #include in normally without any path and then modifying the path using compiler switches for the different builds.
                      I did something like that once, maybe its non-standard. I tried it just now on g++ and it didn't work.

                      There is no string concatenation operator, just a concatenation operator (##) and a stringize operator (#). The stringize operator only works for parameters, where as the concatenation operator works for everything.

                      Oh well. My second and third methods should work (I’ve tested the second on g++, the third will definitely work unless the include file is not in the current directory, then it will get a bit hairy.

                      The best way to do this is not with the preprocessor, but using the -I (capital i) switch on the compiler (or whatever switch it is, -I is somewhat standard though) to state which directory should be searched for the include files.


                      Adrian

                      Comment

                      • Banfa
                        Recognized Expert Expert
                        • Feb 2006
                        • 9067

                        #12
                        Originally posted by AdrianH
                        The best way to do this is not with the preprocessor, but using the -I (capital i) switch on the compiler (or whatever switch it is, -I is somewhat standard though) to state which directory should be searched for the include files.
                        I definitely agree :D

                        Comment

                        • yanjie111
                          New Member
                          • Apr 2007
                          • 14

                          #13
                          Thanks you all.
                          I changed my mind. I don't use the preprocessor to change the path.
                          Change the path in the #include is a bad idea. We can always find a better way to do the same thing.

                          Comment

                          • AdrianH
                            Recognized Expert Top Contributor
                            • Feb 2007
                            • 1251

                            #14
                            Originally posted by yanjie111
                            Thanks you all.
                            I changed my mind. I don't use the preprocessor to change the path.
                            Change the path in the #include is a bad idea. We can always find a better way to do the same thing.
                            Yup.


                            Adrian

                            Comment

                            Working...