Passing multiple values from a function in C

I know multiple values can be returned from a function in C like this:

char **read_file ( char * , unsigned long int * );//this is the function prototype
unsigned long int number_of_words = 0;//variable defined in main() and initialized to 0
words_from_dictionary = read_file ( "dictionary.dit" , &number_of_words );//function call in main()

The function definition that I write later on, outside of main().

char **read_file ( char *path , unsigned long int *number_of_words )
{
    char ch;
    char *line = NULL;
    
    unsigned long int len = 0;
    unsigned long int read;
    
    ( * number_of_words ) = 0;//the updated value of this will be returned
    unsigned long int i = 0;
    unsigned long int j = 0;

    FILE *pointer = NULL;
    char **word_array = NULL;

    pointer = fopen ( path , "r" );//read some file from a path
    if ( pointer == NULL )
    {
        perror ( "File read error: read file" );
    }

    while ( !feof ( pointer ) )
    {
        ch = fgetc ( pointer );
        if ( ch == '\n' && ch != EOF )
        {
            ( * number_of_words ) ++;//counting the number of words in the file, this value will be returned to the main() along with another string array.
        }
    }

    rewind ( pointer );

    word_array = malloc ( ( * number_of_words ) * sizeof ( char * )
);
    if ( word_array == NULL )
    {
        perror ( "malloc() memory allocation failure" );
    }

    for ( i = 0 ; i < ( * number_of_words ) ; i ++ )
    {
        word_array [ i ] = malloc ( 100 * sizeof ( char ) );
        if ( word_array [ i ] == NULL )
        {
            perror ( "malloc() memory allocation failure" );
        }
    }

    i = 0;
    j = 0;

    while ( !feof ( pointer ) )
    {
        while ( ( read = getline ( &line, &len , pointer ) ) != - 1 )
        {
            strcpy ( word_array [ i ] , line );
            if ( i <= ( * number_of_words ) )
            {
                i ++;
            }
        }
    }

    fclose ( pointer );
    return ( word_array );//Returning this array of string
}

I can see that the calling function in main() can read both the number of words and the string array easily.

Now my question is:
If I now have something like this. These variables are defined in main()

 unsigned long int *word_position = NULL;
    unsigned int *document_id = NULL;
    long double *score = NULL;

The calling function in main is like this:

read_score_file ( word_position , document_id , score );

Now later I have a function like this:

void read_score_file ( unsigned long int *word_position , unsigned int *document_id , long double *score )
{
    FILE *score_file = NULL;

    unsigned int i = 0;

    score_file = fopen ( "scores.sce" , "r" );
    if ( score_file == NULL )
    {
        fprintf ( stderr , "file open error: score:file\n" );
    }

    word_position = ( unsigned long int * ) malloc ( TOTAL_WORD_IN_DICS * sizeof ( unsigned long int ) );
    if ( word_position == NULL )
    {
        fprintf ( stderr , "malloc() memory allocation failure" );
    }

    document_id = ( unsigned int * ) malloc ( TOTAL_WORD_IN_DICS * sizeof ( unsigned int ) );
    if ( document_id == NULL )
    {
        fprintf ( stderr , "malloc() memory allocation failure" );
    }

    score = ( long double * ) malloc ( TOTAL_WORD_IN_DICS * sizeof ( long double ) );
    if ( score == NULL )
    {
        fprintf ( stderr , "malloc() memory allocation failure" );
    }

    while ( !feof ( score_file ) )
    {
        int32_t return_value = 0;

        return_value = fscanf ( score_file , "%ld %u %Lg\n" , ( word_position + i ) , ( document_id + i ) , ( score + i ) );
        if ( return_value == -1 )
        {
            break;
        }
        i ++;
    }
}

How can I return all the three variables (address of the first value) word_position, document_id and score to main() so that the parameters in

    read_score_file ( word_position , document_id , score );

in main() have the starting addresses of all the three variables? As of now they are getting NULL from read_score_file() function as return value. This simply means that I want read_score_file() to return multiple values. I am doing my programming in Linux and using gcc-4.1.2.

They are not getting NULL as return value. That NULL is still the initial NULL from main. The reason is that you only pass a pointers to the function. These pointers will be copied to the function stack and then these copies will be used for the function itself.
What you need here are pointers to pointers:

void read_score_file ( unsigned long int **word_position , unsigned int **document_id , long double **score ) {
      *word_posititon = (int *) malloc (...)
}
1 Like

you could also group those data items into a struct and return that struct from the function

1 Like