> I'm trying to return a double pointer from a function. Here is my current code:
But you have a 2D array - which isn't the same thing.
char a[N] becomes a char *
but
char a[R][C] becomes char (*)[C], not char **. The array-becomes-pointer rule only applies to the left-most dimension, not all of them.
If you thought returning a ** was mind-bending enough, you're really not going to like returning a pointer to a 2D array.
Code:
// Declare includes.
#include <errno.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Declare defines.
#define FILENAME_SIZE 100
#define MAX_OLD_DOWNLOADS 10
#define PROGRAM_NAME_SIZE 50
#define YOUTUBE_DATA_DIRECTORY "/dea/youtube_data/"
// Declare global variables.
char program_name[PROGRAM_NAME_SIZE + 1] = {0};
// Declare function prototypes.
char (*get_downloaded_list (char *account))[25];
int main (int argc, char *argv[])
{
// Decalre variables.
char (*downloaded)[25] = {0};
// Get program name for error reporting.
strcpy(program_name, basename(argv[0]));
// Check number of arguments.
if(argc != 1)
{
fprintf(stderr, "Usage: %s\n", program_name);
exit(EXIT_FAILURE);
}
// Get downloaded videos list.
downloaded = get_downloaded_list("AlfieAesthetics");
if(downloaded)
{;}
// Exit cleanly.
exit(EXIT_SUCCESS);
}
char (*get_downloaded_list (char *account))[25]
{
// Declare variables.
int counter = 0;
FILE *fp = NULL;
char filename[FILENAME_SIZE + 1] = {0};
static char downloaded[MAX_OLD_DOWNLOADS][25] = {0};
// Build the filename
strcpy(filename, YOUTUBE_DATA_DIRECTORY);
strcat(filename, account);
// Open the data file for reading.
if((fp = fopen(filename, "r")) == NULL)
{
fprintf(stderr, "%s: get_downloaded_list error: fopen failed (%s) (%s)\n", program_name, strerror(errno), filename);
exit(EXIT_FAILURE);
}
// Loop through all lines in the file.
while(fgets(downloaded[counter], 25, fp) != NULL && counter < MAX_OLD_DOWNLOADS)
{
// Remove trailing newline.
downloaded[counter][strlen(downloaded[counter]) - 1] = '\0';
// Advance counter.
counter++;
}
// Set end marker if list is not maxed out.
if(counter != MAX_OLD_DOWNLOADS)
downloaded[counter][0] = '\0';
// Close the data file.
fclose(fp);
// Return the list.
return(downloaded);
}
But if you really want the char** route (which is more flexible in the long run), then:
Code:
char **get_downloaded_list (char *account)
{
// Declare variables.
int counter = 0;
FILE *fp = NULL;
char filename[FILENAME_SIZE + 1] = {0};
char **downloaded = malloc(MAX_OLD_DOWNLOADS * sizeof(*downloaded));
char buff[25];
// Build the filename
strcpy(filename, YOUTUBE_DATA_DIRECTORY);
strcat(filename, account);
// Open the data file for reading.
if((fp = fopen(filename, "r")) == NULL)
{
fprintf(stderr, "%s: get_downloaded_list error: fopen failed (%s) (%s)\n", program_name, strerror(errno), filename);
exit(EXIT_FAILURE);
}
// Loop through all lines in the file.
while(fgets(buff, sizeof(buff), fp) != NULL && counter < MAX_OLD_DOWNLOADS)
{
// Remove trailing newline.
buff[strlen(buff)-1] = '\0';
// save it
downloaded[counter] = malloc( strlen(buff) + 1 );
strcpy(downloaded[counter], buff);
// Advance counter.
counter++;
}
// Set end marker if list is not maxed out.
if(counter != MAX_OLD_DOWNLOADS)
downloaded[counter] = NULL;
// Close the data file.
fclose(fp);
// Return the list.
return(downloaded);
}