简体   繁体   中英

Passing 2d Arrays by Reference in C

I have been searching and reading for a while now and I can not see why this will not work.

I am passing a 2d array using the & to pass the address of the first location in memory. The function accepts a char *tokens a pointer to that memory location.

The function:

void printOutput( FILE* template, char* tokens)
{
    char c = fgetc(template);

    while(c != EOF )
    {
        if( c != '$' )
        {
            printf("%c", c);
        }
        else
        {
            c = fgetc(template);
            int charVal = c-'0';

            if( charVal >= 0 && charVal <= 9 )
            {
                printf("%d" , charVal);
                printf("%s" , tokens[charVal]);
            }
        }
        c = fgetc(template);
    }
   printf("\n\n");
}

The function is called like this:

printOutput(template, &tokens[0]);

If I put the function code into the main function in place of the printOutput function call, the output is properly displayed.

From what I can tell is that somewhere between the function call and the function running something is happening that turns my tokens[][] into an array of all (null) .

I believe I am address it incorrectly and hope someone can help. I can also provide more code if needed.

I really appreciate any help!

Due to answers helping, but still not solving the issue, I am resorting to adding the main() function from my code.

int main( int argc, char *argv[] )
{
FILE *template = NULL;
FILE *data = NULL;

char input[INPUT_LENGTH];

template = fopen( "template.txt", "r" );
if ( template != NULL )
{
    data = fopen( "data.txt", "r" );
    if ( data != NULL )
    {

        char input[INPUT_LENGTH];

        while ( fgets(input, INPUT_LENGTH, data) )
        {
            char *token = NULL;
            char *tokens[INPUT_LENGTH][FIELD_LENGTH];

            int pos = 0;
            token = strtok(input, "|");
            while(token != NULL )
            {
                tokens[pos][0] = token;
                token = strtok(NULL, "|");
                pos++;
            }

            printOutput(template, tokens[INPUT_LENGTH][FIELD_LENGTH]);

            rewind(template);
        }

        fclose( data );
    }

    fclose( template );
}

return EXIT_SUCCESS;

}

I can only now assume the issue has to do with the char *tokens[INPUT_LENGTH][FIELD_LENGTH]; declaration, but I am totally unsure at this point.

Your 2D array char tokens[X][LEN] is laid out in memory as:

Value     : Mem addresses for char[LEN]

tokens[0] :         0 . . . LEN-1
tokens[1] :       LEN . . . 2*LEN-1
tokens[X-1] : (X-1)*LEN . . . X*LEN - 1

Conversely, char* tokens is interpreted as:

Value     : Mem addresses for char

tokens[0] : 0
tokens[1] : 1
tokens[2] : 2

Now, when you pass these to printf with a string format, you're dereferencing the value to a char , not a char* like it expects. Hence the bad output / undefined behaviour.

Even if you took the address ( printf("%s" , &tokens[charVal]); ), it would still not give you your expected result because it's resolving to the wrong address.

Since your 2D array has a fixed size, you should declare the function like this:

void printOutput( FILE* template, char tokens[X][LEN] )

Where X and LEN are the two array dimensions, obviously... In case it wasn't clear after my prolific use of them above =)

This way, the compiler knows exactly how to interpret tokens[charVal] , which will be an array type that decays to a char* .


[Edit, since you provided more information and code]

You are still getting confused between char* and char with your arrays. I've corrected this, as tokens should be a one-dimensional array of char* .

        char *tokens[INPUT_LENGTH] = { 0 };

        int pos = 0;
        token = strtok(input, "|");
        while(token != NULL )
        {
            tokens[pos] = token;
            token = strtok(NULL, "|");
            pos++;
        }

        printOutput(template, tokens);

Also, printOutput should be defined as:

void printOutput( FILE* template, char** tokens)

From the following printf statement inside printOutput (), I believe you are trying to access tokens as if it is an array of strings. printf("%s" , tokens[charVal]);

But you have declared tokens as just a char pointer in printOutput (), which can at best only stand-in for an array of characters (or in other words just 1 string if it is null terminated).

Either you need to declare it as a double dimension array

void printOutput (FILE* template, char tokens[MAX_STRINGS] [MAX_CHARS_IN_STRING])

Or declare it as a pointer to array of characters

void printOutput (FILE* template, char (*tokens) [MAX_CHARS_IN_STRING])

and call it as

printOutput(template, tokens);

You are passing tokens as a 'char *', however, what you are trying to do, is to pass a 'char **', namely, a pointer to a pointer that points to the first element of your 2D array.

Try this:

void printOutput( FILE* template, char** tokens)

And call it as follows:

printOutput(template, tokens);

Note that you want all 'char *' in tokens to have a '\\0' terminator.

eg tokens[0] = {'a','b','c','\\0'} or tokens[0] = "abc" since printf won't know where to stop printing '%s'otherwise

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM