Michael Cruz
Michael Cruz

Reputation: 27

How can a function return self-defined struct?

I am trying to scan the input file inside a function, instead of scaning the inputfile in the main function. but seems like it doesn't work this way. I guess it's the problem of the inputfile pointer, I am not very familiar with using pointers

#include<stdio.h>

typedef struct 
{
    char firstname[32],lastname[32];
    int age;
}mandef;

mandef scaninput(int rows,FILE *inputfile)
{
    int i;
    mandef man[rows];
    for (i = 0; i < rows; i ++)
    {
        fscanf(inputfile,"%s",&man[i].firstname);
        fscanf(inputfile,"%s",&man[i].lastname);
        fscanf(inputfile,"%d",&man[i].age);
    }
    return man;
}

int main ()
{
    FILE *inputfile;
    inputfile = fopen("input.txt","r");
    if (inputfile == NULL)
    {
        printf("Error: Unable to open input.txt.");
        return(1);
    }
    int i,rows;
    char x;
    fscanf(inputfile,"%d",&rows);
    mandef man[rows];
    man = scaninput(rows,inputfile);
    return 0;
}

I want the code works the same way as this code

#include<stdio.h>
typedef struct 
{
    char firstname[32],lastname[32];
    int age;
}mandef;

int main ()
{
    FILE *inputfile;
    inputfile = fopen("input.txt","r");
    if (inputfile == NULL)
    {
        printf("Error: Unable to open input.txt.");
        return(1);
    }
    int i,rows;
    fscanf(inputfile,"%d",&rows);
    mandef man[rows];
    for (i = 0; i < rows; i ++)
    {
        fscanf(inputfile,"%s",&man[i].firstname);
        fscanf(inputfile,"%s",&man[i].lastname);
        fscanf(inputfile,"%d",&man[i].age);
    }
    return 0;
}

input.txt looks like

2
Mike Abc 18
David Abc 17

Upvotes: 0

Views: 73

Answers (2)

Hitokiri
Hitokiri

Reputation: 3699

You return the local variable, it's a bad idea because after the function terminated, this variable may be doesnt existe. So you should use pointer instead:

mandef * man = malloc(sizeof(mandef) * rows);
if(!mandef) {
   // handle the error
}

Do not use & for scanning the string, it should be:

        fscanf(inputfile,"%s",man[i].firstname);
        fscanf(inputfile,"%s",man[i].lastname);
        fscanf(inputfile,"%d",&man[i].age);

the test:

#include<stdio.h>
#include <stdlib.h>

typedef struct 
{
    char firstname[32],lastname[32];
    int age;
}mandef;

mandef * scaninput(int rows,FILE *inputfile)
{
    int i;
    mandef * man = malloc(sizeof(mandef) * rows);
    if (!man) {
        return NULL;
    }
    for (i = 0; i < rows; i ++)
    {
        fscanf(inputfile,"%s",man[i].firstname);
        fscanf(inputfile,"%s",man[i].lastname);
        fscanf(inputfile,"%d",&man[i].age);
    }
    return man;
}

int main ()
{
    FILE *inputfile;
    inputfile = fopen("input.txt","r");
    if (inputfile == NULL)
    {
        printf("Error: Unable to open input.txt.");
        return(1);
    }
    int i,rows;
    char x;
    fscanf(inputfile,"%d",&rows);
    if(rows <= 0)
       return -1;
    mandef * man;
    man = scaninput(rows,inputfile);
    for (i = 0; i < rows; i ++)
    {
        printf("%s\n",man[i].firstname);
        printf("%s\n",man[i].lastname);
        printf("%d\n",man[i].age);
    }
    free(man);
    return 0;
}

the output:

Mike                                                                                                                                            
Abc                                                                                                                                             
18                                                                                                                                              
David                                                                                                                                           
Abc                                                                                                                                             
17

Upvotes: 1

CodeWash
CodeWash

Reputation: 185

I would recommend that you figure out pointers and dynamically allocating memory for your array using malloc if that is appropriate. I made some quick changes to your code below, it's far from perfect but it should give you the general idea.

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

typedef struct mandef
{
    char firstname[32];
    char lastname[32];
    int age;
} mandef;

mandef *scaninput(int rows,FILE *inputfile)
{
    int i;
    mandef *man = malloc(sizeof(mandef) * rows);
    bzero(man, (sizeof(mandef) * rows));

    for (i = 0; i < rows; i++)
    {
        fscanf(inputfile,"%31s",man[i].firstname);
        fscanf(inputfile,"%31s",man[i].lastname);
        fscanf(inputfile,"%d",&man[i].age);
    }
    return man;
}

int main ()
{
    FILE *inputfile = fopen("input.txt","r");

    if (inputfile == NULL)
    {
        printf("Error: Unable to open input.txt.");
        return(1);
    }

    int rows=0;

    fscanf(inputfile,"%d",&rows);
    mandef *man = scaninput(rows,inputfile);
    if (rows > 0) 
    {
        printf("man[0].firstname is %s\n", man[0].firstname);
    }
    return 0;
}

Upvotes: 1

Related Questions