How to initialize an array of pointers to an array of characters?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • paul321thnx
    New Member
    • May 2014
    • 10

    How to initialize an array of pointers to an array of characters?

    Hello,

    I am trying to initialize an array of pointers to an array of characters, I can do it in 3 lines but I really want to do it in one line at the same time keeping the #define.

    3 lines initialization (can compile)
    =============== =======
    #define A 1
    #define B 2
    char row1[] = {A|B, B, A};
    char row2[] = {B, A};
    char *test[]= {row1, row2};

    1 line initialization (failed)
    =============== =============== =
    char *test[] = { {A|B, B, A}, {B, A} }; // <- how do i do this??

    I do not want this because it waste ROM space
    =============== =============== ===============
    char test[][3] = { {A|B, B, A}, {B, A} };


    Much appreciate if anyone can give me some pointers, thnx - paul.
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    Row 1 has three elements, but row 2 only has two elements. How do you plan to keep track of how many elements are in each row? You basically have two options: specify the row size explicitly (add a field to specify it) or implicitly (hard-coded into the logic of your software.

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      Code:
      char *test[] = { {A|B, B, A}, {B, A} }; // <- how do i do this??
      Here test is an array of char pointers. Unfortunately, A and B are integers so they can't used as char pointers.

      BTW: The nested braces don't do anything other than group items for the human eye. Braces do not create arrays.

      You will need to:
      1) Create your char arrays.
      2) Create your char pointer array
      3) assign the address of element 0 of each char array to and element of your char pointer array.

      You might want to read: http://bytes.com/topic/c/insights/77...rrays-revealed

      Comment

      • paul321thnx
        New Member
        • May 2014
        • 10

        #4
        Hi donbock,

        thanks for your reply. yes, i intend to add a termination character to mark the end of the row. That aside, are you aware of how this could be done in one line?

        Comment

        • paul321thnx
          New Member
          • May 2014
          • 10

          #5
          Hi weaknessforcats ,

          You will need to:
          1) Create your char arrays.
          2) Create your char pointer array
          3) assign the address of element 0 of each char array to and element of your char pointer array.


          That is exactly what i did in my example but I need to do it in one line something like this:

          char *test[] = { {A|B, B, A}, {B, A} };

          I know it is not the correct syntax, but if it can be done in 3 lines surely it can be done in one line. Is there no way?

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            Why is it so important to write this on one line?

            You already know one way to do it: declare test as a 2-dimensional char array. However, then all rows will be the same length. You don't like this approach.

            I can think of one other way to do it -- by declaring each row as a string. However, it would be hard to still use the #defines. Also, with strings you have no choice in what the row-termination character will be.

            Comment

            • paul321thnx
              New Member
              • May 2014
              • 10

              #7
              Originally posted by donbock
              Why is it so important to write this on one line?

              You already know one way to do it: declare test as a 2-dimensional char array. However, then all rows will be the same length. You don't like this approach.

              I can think of one other way to do it -- by declaring each row as a string. However, it would be hard to still use the #defines. Also, with strings you have no choice in what the row-termination character will be.


              you do not appreciate the magnitude of the problem with the 5 line code i provided.
              instead of 2 rows, say I have 100s of rows of different sizes. That means I have to use 100s of row labels and the last line would have to look something like this:

              char *test[] = {row1, row2, .. row 999};

              If i can do it in a "one-line" syntax, I can do it in a tabular form and that save a lot of work. of course i can write a pre-processor but that is another discussion.

              char test[][5]

              is no good because a few of my rows are 100s char long and the rest are 10s char long, i would have wasted a lot of space which I cannot afford.

              I cannot do this:

              char *test[] = { "x\abx\12", "x\ed" }

              because I need the #define.

              Comment

              • donbock
                Recognized Expert Top Contributor
                • Mar 2008
                • 2427

                #8
                I can't think of a clever way to do what you want in C.

                Take a look at C Preprocessing with TCL from 1998 article in Dr Dobbs.

                Comment

                • weaknessforcats
                  Recognized Expert Expert
                  • Mar 2007
                  • 9214

                  #9
                  Code:
                  char *test[] = {row1, row2, .. row 999};
                  You are forcing yourself into this by having the arrays all available at compile time.

                  Consider creating the arrays on the heap at run time and storing the address of the array in your array of char pointers.

                  None of the char arrays would need a label.

                  Note also that having everything on the stack may cause a stack boundary overflow and crash your program.

                  Extremely large database machines, like Oracle, are written in C and do not have problems with labels.

                  Comment

                  • paul321thnx
                    New Member
                    • May 2014
                    • 10

                    #10
                    @ weaknessforcats

                    you are making things more complicated than it need be. perhaps it is my fault not to make things absolutely clear. The initialization values would go into ROM. I should have added the "const" in my declaration. There will be no problems with heaps or stacks, i know that.

                    i don't have a problem with labels per see. they are needed to initialize the final constant array. How do you suggest i

                    "assign the address of element 0 of each char array to and element of your char pointer array." without a label? how do i reference that char array to do this without a label?

                    i knew about the solutions offered by yourself and donbock but have discounted them before i posted this question, nevertheless, i appreciate your effort. thank you. what i am really looking for is a one-line syntax because if it can be done on multiple lines, it can usually be done in one line perhaps with some ugly casting and braces.

                    I would like to hear from C experts or c compilers writers if this is indeed possible (ie within the ANSI C specification), if the language does not support it, so be it.

                    Comment

                    • paul321thnx
                      New Member
                      • May 2014
                      • 10

                      #11
                      @ donbock

                      thanks for the heads up. I am not stuck, i do have a solution, just that it is not "nice" and I am curious if it can be done in a "one-line" syntax, if it cannot be done, so be it, no worries. thnx

                      Comment

                      • donbock
                        Recognized Expert Top Contributor
                        • Mar 2008
                        • 2427

                        #12
                        Originally posted by paul321thnx
                        I cannot do this:

                        char *test[] = { "x\abx\12", "x\ed" }

                        because I need the #define.
                        The following example relies on implicit string concatenation. Would something like this work for you:
                        Code:
                        #define A "\x01"
                        #define B "\x02"
                        #define AorB "\x03"    // A|B
                        ...
                        
                        char *test[] = {
                             AorB B A,
                             B A
                             ...
                        };
                        By the way, you are using char as an integral type. This is inadvisable because whether or not char is signed is implementation-dependent. You will get more reliable and portable behavior using unsigned char. However, that isn't compatible with the string approach.

                        Comment

                        • paul321thnx
                          New Member
                          • May 2014
                          • 10

                          #13
                          @donbock

                          almost but not quite, i need the compiler to do those AND OR ADD etc for me at compile time and i want to leave them as A|B, A&B for easy reference (yes, i can put a comment like what you did). and, yes i am picky! ;)

                          thanks for the unsigned char tip though.

                          Comment

                          • weaknessforcats
                            Recognized Expert Expert
                            • Mar 2007
                            • 9214

                            #14
                            Maybe you could try:

                            Code:
                            char array[10] = { A | B, B, A,B,A,A,B,B,A&B };
                            char *test[] = { &array[0], &array[2], &array[4]};
                            There really is no such thing as an array in C. All you have is a memory allocation that you can view however you like. You are allowed the [] syntax but that is just so the compiler can do pointer arithmetic.

                            There is an example of this in the insight I recommended.

                            Here the array test has 3 pointers to char arrays.

                            Comment

                            • donbock
                              Recognized Expert Top Contributor
                              • Mar 2008
                              • 2427

                              #15
                              @paul321thnx
                              I'm out of ideas. Good luck.

                              Comment

                              Working...