简体   繁体   English

在C中通过引用传递2d数组

[英]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. 我正在使用&传递2d数组&以传递内存中第一个位置的地址。 The function accepts a char *tokens a pointer to that memory location. 该函数接受一个char *tokens指向该内存位置的指针。

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. 如果我将函数代码代替printOutput函数调用放入主函数中,则输出将正确显示。

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) . 据我所知,在函数调用和函数运行之间的某个地方发生了某种事情,这使我的tokens[][]变成了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. 由于答案有所帮助,但仍不能解决问题,因此我求助于从代码中添加main()函数。

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]; 我现在只能假设问题与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: 您的2D数组char tokens[X][LEN]在内存中的布局方式为:

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: 相反, char* tokens被解释为:

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. 现在,当您将它们以字符串格式传递给printf时,您是在将值取消引用给char ,而不是像期望的char*那样。 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. 即使您使用了该地址( printf("%s" , &tokens[charVal]); ),也仍然无法获得预期的结果,因为它解析为错误的地址。

Since your 2D array has a fixed size, you should declare the function like this: 由于2D数组的大小是固定的,因此应声明以下函数:

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 =) XLEN是两个数组的维数,显然...万一我在上面大量使用它们后还不清楚,

This way, the compiler knows exactly how to interpret tokens[charVal] , which will be an array type that decays to a char* . 这样,编译器确切地知道如何解释tokens[charVal] ,它们将是一个衰减为char*的数组类型。


[Edit, since you provided more information and code] [编辑,因为您提供了更多信息和代码]

You are still getting confused between char* and char with your arrays. 您仍然对数组的char*char之间感到困惑。 I've corrected this, as tokens should be a one-dimensional array of char* . 我已经更正了这一点,因为tokens应该是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: 另外, printOutput应该定义为:

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. 从以下printOutput()中的以下printf语句中,我相信您正在尝试访问令牌,就好像它是字符串数组一样。 printf("%s" , tokens[charVal]); 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). 但是,您已经将标记声明为printOutput()中的一个char指针,该指针最多只能代表一个字符数组(或者,如果以null终止,则只能是1个字符串)。

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. 您将令牌作为“ char *”传递,但是,您要尝试的是传递“ char **”,即指向2D数组第一个元素的指针的指针。

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. 请注意,您希望令牌中的所有“ char *”都具有“ \\ 0”终止符。

eg tokens[0] = {'a','b','c','\\0'} or tokens[0] = "abc" since printf won't know where to stop printing '%s'otherwise 例如tokens [0] = {'a','b','c','\\ 0'}或tokens [0] =“ abc”,因为printf不知道从何处停止打印'%s'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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