Thread: How define array type with 4 elements?

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    235

    Question How define array type with 4 elements?

    How can I define type MARKS which will be able to hold 4 elements just like array? I want to access it just like normal array elements using brackets []. In the following struct I want to use such type.

    Code:
    typedef struct {
    
        MARKS ** pointers;
    
    } ARGUMENTS
    
    
    void main(){
    ARGUMENTS arguments;
    arguments[counter][0]; // type char *
    arguments[counter][1]; // type char *
    arguments[counter][2]; // type char *
    arguments[counter][4]; // type char *
    }
    Yet I am not sure with the type char *

    Purpose of the struct ARGUMENTS is to hold 4 pointers to string. I want to mark few positions in string so I can simple access them. E.g. name=John
    Code:
    arguments[0][0]=0; // begin of the param name
    arguments[0][1]=3; // end of the param name
    arguments[0][2]=5; // begin of the value
    arguments[0][3]=8; // end of the value
    I mean not to save int but the pointer to the corresponding position.
    Last edited by barracuda; 01-18-2015 at 03:47 PM.

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Code:
    typedef struct {
        char *pointers[4];
    } ARGUMENTS;
    This gives you an array of 4 pointers.
    bit∙hub [bit-huhb] n. A source and destination for information.

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Wait, this doesn't make sense for me. I don't want create member "pointers".

    I need the type ARGUMENTS to stay in the form as specified:
    Code:
    typedef struct {
        MARKS ** pointers;
    } ARGUMENTS
    Because ARGUMENTS must keep pointer to pointer of type MARKS. Where MARKS should be array with maximum 4 elements.

    As you could see in my example
    Code:
    arguments[0][0]=0;
    arguments[0][1]=3;
    arguments[0][2]=5;
    arguments[0][3]=8;
    I don't have there any member pointers.
    Last edited by barracuda; 01-19-2015 at 03:36 PM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Can't do that in C.

    Arrays, pointers, and structs are not interchangeable, so array syntax cannot be used to access information from a struct.


    Unrelated to your question, main() returns int, not void.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    I cannot edit the previous post, so correction:
    the form
    Code:
    typedef struct {
    
        MARKS ** pointers;
    
    } ARGUMENTS
    Should not contain member pointers. I need to change it somehow that I could access it like so:
    Code:
    arguments[0][0]=0;
    
    arguments[0][1]=3;
    
    arguments[0][2]=5;
    
    arguments[0][3]=8;

  6. #6
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    grumpy: never mind, thanks still. I can use the syntax
    Code:
    char *** array;
    but I wanted to save me of the need to allocate memory for second level of the array.

  7. #7
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    You don't really want a triple-pointer.

    Quote Originally Posted by http://c2.com/cgi/wiki?ThreeStarProgrammer
    A rating system for C-programmers. The more indirect your pointers are (i.e. the more "*" before your variables), the higher your reputation will be. No-star C-programmers are virtually non-existent, as virtually all non-trivial programs require use of pointers. Most are one-star programmers. In the old times (well, I'm young, so these look like old times to me at least), one would occasionally find a piece of code done by a three-star programmer and shiver with awe.

    Some people even claimed they'd seen three-star code with function pointers involved, on more than one level of indirection. Sounded as real as UFOs to me.

    Just to be clear: Being called a ThreeStarProgrammer is usually not a compliment.
    I think it is better to define the MARKS like:

    Code:
    typedef struct marks_t {
        char *name_begin;
        char *name_end;
        char *value_begin;
        char *value_end;
    } MARKS;
    You can access it with:
    Code:
    typedef struct arguments_t {
    
        MARKS marks;
    
    } ARGUMENTS;
    
    
    int main (void) {
    
        ARGUMENTS arguments[10];
    
        arguments[0].marks.name_begin = 0;
        arguments[0].marks.name_end = 3;
        arguments[0].marks.value_begin = 5;
        arguments[0].marks.value_end = 8;
    }
    The 4 values should be char *.
    Or if you want the position of start and end?
    Then it will be better to define it as size_t.
    (Not tested, only a quick shot)
    Last edited by WoodSTokk; 01-19-2015 at 08:14 PM.
    Other have classes, we are class

  8. #8
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by barracuda View Post
    I want to mark few positions in string so I can simple access them. I mean not to save int but the pointer to the corresponding position.
    Define a suitable mark structure. Note that instead of a pointer to end, it's easier to use length, as then you can use e.g. strncmp("name", name, name_len) to compare such. (Besides, name_end = name + name_len anyway.)

    Here is an example:
    Code:
    typedef struct {
        const char *name;
        size_t      name_len;
        const char *value;
        size_t      value_len;
    } pair;
    Although you can just use a pair with name=NULL, name_len=0, value=NULL, value_len=0 as the end-of-array pair, checking all four to detect it is a bit tedious, so I'd define a pair array structure with the array size counter, so no such special pairs are needed:
    Code:
    typedef struct {
        size_t items;
        pair  *item;
    } pair_array;
    If you often append new elements to an array, you might wish to use two counters instead, one for the number of elements you've allocated memory for in item, and the other for the actual item count (like items above).

    Your arguments would then be just an array of pair arrays. You could use a special pair array ( items=0, item=NULL ) as an end of arguments marker, but I think a counter is better. Assuming these are global parameters, you can just make them global variables:
    Code:
    size_t      arguments;
    pair_array *argument;
    Assuming you've done all the allocations, and the indexes are within the allocated limits, you could then access them using
    Code:
    /* Assuming (arguments > 5) && (argument[5]->items > 3) */
    
    argument[5].item[3].name
    argument[5].item[3].name_len
    /* (argument[5].item[3].name + argument[5].item[3].name_len) is the end pointer */
    
    argument[5].item[3].value
    argument[5].item[3].value_len
    /* (argument[5].item[3].value + argument[5].item[3].value_len) is the end pointer */
    Technically, this is three-star code; we have pointer (argument) to pointer (item) to pointer (name, or value), but having dedicated types or structures makes it pretty readable.

    Dynamic memory management for these is simple:
    Code:
    /* Return a pointer to pair p in argument a,
     * extending the arrays as needed.
    */
    pair *get_pair(const size_t a, const size_t p)
    {
        if (a >= arguments) {
            argument = realloc(argument, (a + 1) * sizeof *argument);
            if (new_array == NULL) {
                fprintf(stderr, "Out of memory.\n");
                exit(EXIT_FAILURE);
            }
            while (arguments <= a) {
                argument[arguments].items = 0;
                argument[arguments].item = NULL;
                arguments++;
            }
        }
    
        {
            pair_array *const array = argument + a;
    
            if (p >= array->items) {
                array->item = realloc(array->item, (p + 1) * sizeof *array->item);
                if (array->item == NULL) {
                    fprintf(stderr, "Out of memory.\n");
                    exit(EXIT_FAILURE);
                }
                while (array->items <= p) {
                    array->item[array->items].name = NULL;
                    array->item[array->items].name_len = 0;
                    array->item[array->items].value = NULL;
                    array->item[array->items].value_len = 0;
                    array->items++;
                }
            }
    
            return array + a;
        }
    }
    with quite simple usage,
    Code:
        pair *p;
    
        p = get_pair(5, 3);
        /* p->name      == argument[5].item[3].name
         * p->name_len  == argument[5].item[3].name_len
         * p->value     == argument[5].item[3].value
         * p->value_len == argument[5].item[3].value_len
        */
    Since get_pair() aborts the program in case reallocation fails, there is no need to worry about freeing the old arrays, as the OS/kernel will handle that for us.

    In case you wonder, (argument + a) is just a simpler way to write "pointer to element a in argument", &(argument[a]).

  9. #9
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    OK, thanks. I'll have to remake it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. proper way to define a variable type
    By killme in forum C++ Programming
    Replies: 12
    Last Post: 09-20-2013, 02:24 AM
  2. Define a macro to sum the elements of an array
    By volte in forum C Programming
    Replies: 6
    Last Post: 07-22-2011, 04:22 AM
  3. Is it possible to set type for define macro?
    By 6tr6tr in forum C++ Programming
    Replies: 5
    Last Post: 04-16-2008, 01:32 PM
  4. how to define a range of type in C++ or C?
    By zaracattle in forum C++ Programming
    Replies: 24
    Last Post: 03-23-2007, 03:31 PM
  5. define a boolean type
    By Krem in forum C Programming
    Replies: 6
    Last Post: 10-04-2002, 11:54 AM