asked    Harriet     2018-10-22       c       44 view        2 Answers

[SOLVED] ANSI C: Declare a pointer of type "array of string"

I have a structure like this

struct {
  int    id;
  char   str00[10];
  char   str01[10];
  char   str03[10];
  char   str04[10];
  ...
}   myStructure;

All strXX have the same size. I would like to access them via an array (strArray), like this :

strcpy(strArray[i], strValue);

How to declare strArray ?

I used this:

char   (*strArray)[][10] = (void *)&myStructure.str00;

It's working, but I have to code the strcpy like this

strcpy((*strArray)[i], strValue);

... and I don't like this :-)

Is there another way to declare strArray ?

Thanks for your ideas and help.

  2 Answers  

        answered    Arvin     2018-10-22      

You almost had it, the correct pointer type is simply char (*ptr)[10].

Naively, you could use this pointer type to iterate over the struct members, but doing so would invoke undefined behavior. Because strictly speaking, a pointer can only point at single item or an array, and if we use pointer arithmetic to go beyond that single item/array, we invoke undefined behavior.

I'll include an example still, for the sake of demonstrating array pointer arithmetic:

// BAD CODE, it relies on undefined behavior!

#include <stdio.h>
#include <string.h>

typedef struct {
  int    id;
  char   str00[10];
  char   str01[10];
  char   str02[10];
  char   str03[10];
} myStructure;


int main(void)
{
  myStructure ms = { 0 };
  char (*ptr)[10] = &ms.str00;

  for(size_t i=0; i<4; i++)
  {
    strcpy(ptr[i], "hello ");
    strcat(ptr[i], (char[]){i+'0', '\0'});
  }

  puts(ms.str00);
  puts(ms.str01);
  puts(ms.str02);
  puts(ms.str03);

  return 0;
}

The proper solution is to instead use a union, so that you can access the members either individually, or as an array:

typedef union {
  struct              // anonymous struct, requires a standard C compiler
  {
    char str00[10];
    char str01[10];
    char str02[10];
    char str03[10];
  };
  char array[4][10];
} str_t;

typedef struct {
  int    id;
  str_t  str;
} myStructure;


strcpy(ms.str.array[i], ...); // access as array
puts(ms.str.str00); // access as individual item


        answered    Aaron     2018-10-22      

The cleanest way to define strArray as requested would be to make it an array of pointers to the (first elements of the) arrays in myStructure:

char *strArray[] = { myStructure.str00, myStructure.str01, myStructure.str03, myStructure.Str04, … };

With this definition, strArray[i] is initialized to the corresponding member of the structure, such as myStructure.str01. Note that myStructure.str01 will be automatically converted to a pointer to its first element, so strArray[i] is a pointer to the first char in one of the arrays.

Then strArray[i][j] is char j of array i.

(Incidentally, you skip str02 in your sample code. I do not know why but have retained that in the code above.)

An alternative method would be to use a union, which can be done in various ways, one of which is:

struct
{
    int    id;
    union
    {
        struct
        {
            char   str00[10];
            char   str01[10];
            char   str03[10];
            char   str04[10];
            ...
        };
        char strArray[number of arrays][10];
    };
} myStructure;

That is generally a poor design, as it is needlessly confusing. (While this has a technical possibility of failure due to padding between the individually defined arrays, assertions can be used to ensure this does not occur, or rather to detect when it does.)

Most often, we would simply define the strings as an array of arrays:

struct
{
    int id;
    char str[number of arrays][10];
} my Structure;

Then the members would always be referred to by index, such as myStructure.str[1], and not by individual names, such as myStructure.str01.





Your Answer





 2018-10-22         Marjorie

React + Redux + Babel (SyntaxError in ...state unexpected token)

i try to repeat the example:https://github.com/reduxjs/redux/tree/master/examples/async/srcBut i use last versions of React, Redux and Babel (in example was React v15.5). I don't change anything in this example, and then i try to build it with webpack i get SyntaxError here: 22 | case INVALIDATE_SUBREDDIT: 23 | return {> 24 | ...state, | ^ 25 | didInvalidate: true 26 | }In the ./reducers/index.jsconst posts = (state = { isFetching: false, didInvalidate: false, items: []}, action) => { switch (action.type) { case I...
 javascript                     2 answers                     22 view
 2018-10-22         Blanche

Expo firebase auth provider is undefined

I'm using firebase facebook for my app. I just want user's public profile so that I can create user in my database. I do not want firebase full authentication just the profile detail but I am getting the following error.Here is some codeconst firebaseConfig = { apiKey: FIREBASE_KEY, authDomain: FIREBASE_AUTH_DOMAIN, databaseURL: FIREBASE_DATABASE_URL, projectId: FIREBASE_PROJECT_ID, storageBucket: FIREBASE_STORAGE_BUCKET}export const Firebase = firebase.initializeApp(firebaseConfig);async loginWithFacebook(navigate){ const { type, token} = await Expo.Facebook.logInWit...
 firebase                     1 answers                     23 view
 2018-10-22         Marina

React-native ListView "Warning: Can't call setState"

hey guys could someone please look over this. I cant find where its comming from i've been looking on this page the last days and i cant find itthe Problem is everytime when i`m clicking on one of the names in the list the navigation and the Transver of the Values to "global.dialed" works perfektly but im always getting this warning and the app seems to perform a little slower after that (but the slower performance is very minor and probably just an illusion)Full error:Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates...
 android                     1 answers                     22 view