How do I pass an array of structures to a function? - c

I'm trying to pass an array of structs to a function which fills them with data.
When I try to compile the code I am told that there is an error:
In function 'main':
error: expected expression before 'Robot_t'
loading_Profiles (Robot_t RobotInfo[]);
I am not sure what I am missing?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
typedef struct {
int Robot_Number;
char Robot_Name[30];
int Year_Manufacturer;
float Top_Speed;
float Mass;
float Best_Score;
} Robot_t;
void loading_Profiles();
int main()
{
Robot_t RobotInfo[5];
loading_Profiles (Robot_t RobotInfo[]);
int i;
for (i = 0; i < 50; i++) {
printf("%d\t\t%s\t\t%d\t\t\t%.2f\t\t%.2f\t\t%.2f\n",
RobotInfo[i].Robot_Number, RobotInfo[i].Robot_Name,
RobotInfo[i].Year_Manufacturer, RobotInfo[i].Top_Speed,
RobotInfo[i].Mass, RobotInfo[i].Best_Score);
}
return 0;
}
void loading_Profiles()
{
int Counter = 0;
int i;
Robot_t RobotInfo[5];
FILE *ROBOTtxt = fopen("Robot.txt", "r");
if (ROBOTtxt == NULL) {
perror("an error occured during the loading of the file\n");
exit(-1);
}
for (i = 0; i < 50; i++) {
char LineNumber[100] = "";
fgets(LineNumber, 100, ROBOTtxt);
sscanf(LineNumber, "%d %s %d %f %f %f",
&RobotInfo[i].Robot_Number,
RobotInfo[i].Robot_Name,
&RobotInfo[i].Year_Manufacturer,
&RobotInfo[i].Top_Speed,
&RobotInfo[i].Mass,
&RobotInfo[i].Best_Score);
Counter++;
if (feof(ROBOTtxt)) {
break;
}
}
if (ferror(ROBOTtxt)) {
perror("an error has occured");
exit(-1);
}
fclose(ROBOTtxt);
}

There are several issues with your program. The obvious one is that your function prototypes do not match:
void loading_Profiles()
should be
void loading_Profiles(Robot_t *robots)
in both the declaration and definition.
The array Robot_t RobotInfo[5] in main, and the Robot_t RobotInfo[5] in loading_Profiles do not refer to the same array. They are separate arrays, local to each function. You need to pass the array from main to the loading_Profiles function, which should then modify the array.
Your code also contains various size errors. You are defining an array of 5 elements, and then trying to read and write up to 50 elements. Beyond the mismatch, you need to think about what happens if your file contains less lines than expected.
Counter is unused. As are the return values of some functions that can indicate status / errors:
fgets already partially indicates if it has reached EOF by returning NULL.
sscanf returns the numbers of conversions that took place, which can be used to make sure a partial set of data wasn't stored.
Here is a rewritten example that showcases how to pass arrays around, fill them to a maximum, and utilize the return values of stdio functions. Notice how the type signature of load_robot_profiles matches exactly between the declaration, definition, and invocation of the function.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int number;
char name[32];
int year_manufactured;
float top_speed;
float mass;
float best_score;
} Robot;
size_t load_robot_profiles(Robot *, size_t, const char *);
int main(void) {
Robot robots[5];
size_t length = load_robot_profiles(robots, 5, "robots.txt");
for (size_t i = 0; i < length; i++) {
Robot *r = &robots[i];
printf("%d\t%s\t%d\t\t%.2f\t%.2f\t%.2f\n",
r->number, r->name, r->year_manufactured,
r->top_speed, r->mass, r->best_score);
}
}
size_t load_robot_profiles(Robot *robots, size_t size, const char *fname) {
size_t i = 0;
FILE *file = fopen(fname, "r");
char input[128];
if (!file)
return 0;
while (i < size && fgets(input, sizeof input, file)) {
Robot *r = &robots[i];
if (6 == sscanf(input, "%d %s %d %f %f %f",
&r->number, r->name, &r->year_manufactured,
&r->top_speed, &r->mass, &r->best_score))
i++;
}
fclose(file);
return i;
}
Also note: Defining a type with a _t suffix is ill-advised, as eventually you will brush up against a conflict with an existing POSIX type, or other standard.

Your definition and declaration of the function void loading_Profiles() don't include any arguments, but you're calling it with an argument: loading_Profiles (Robot_t RobotInfo[]);.
You need to change the function to accept Robot_t RobotInfo[] as an argument and then modify the RobotInfo[] array.

The function signature should be like that:
void loading_Profiles(Robot_t* RobotInfo);
Also, there is no need to redeclare the Robot_t RobotInfo[5] inside your loading_Profiles function, since it is already passed by the function call.

Related

How to pass an array of structures in a function? [duplicate]

This question already has answers here:
How do I pass an array of structures to a function?
(3 answers)
Closed 1 year ago.
About to ready to give up on this
Been having an issue with my code for hours, has been telling me I have an error about the error: expected expression before 'Robot_t' and cannot find a solution, if anyone has a working solution you will save me
This is the error message provided
Arrayintofn.c: In function 'main':
Arrayintofn.c:23:23: error: expected expression before 'Robot_t'
loading_Profiles (Robot_t RobotInfo[]);
No matter what I do or who I consult there is no solution
Here is the code as well
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
typedef struct
{
int Robot_Number;
char Robot_Name[30];
int Year_Manufacturer;
float Top_Speed;
float Mass;
float Best_Score;
} Robot_t;
void loading_Profiles();
int main()
{
Robot_t RobotInfo[5];
loading_Profiles (Robot_t RobotInfo[]);
int i;
for (i = 0; i < 50; i++) {
printf("%d\t\t%s\t\t%d\t\t\t%.2f\t\t%.2f\t\t%.2f\n",
RobotInfo[i].Robot_Number, RobotInfo[i].Robot_Name,
RobotInfo[i].Year_Manufacturer, RobotInfo[i].Top_Speed,
RobotInfo[i].Mass, RobotInfo[i].Best_Score);
}
return 0;
}
void loading_Profiles()
{
int Counter = 0;
int i;
Robot_t RobotInfo[5];
FILE *ROBOTtxt = fopen("Robot.txt", "r");
if (ROBOTtxt == NULL) {
perror("an error occured during the loading of the file\n");
exit(-1);
}
for (i = 0; i < 50; i++) {
char LineNumber[100] = "";
fgets(LineNumber, 100, ROBOTtxt);
sscanf(LineNumber, "%d %s %d %f %f %f",
&RobotInfo[i].Robot_Number,
RobotInfo[i].Robot_Name,
&RobotInfo[i].Year_Manufacturer,
&RobotInfo[i].Top_Speed,
&RobotInfo[i].Mass,
&RobotInfo[i].Best_Score);
Counter++;
if (feof(ROBOTtxt)) {
break;
}
}
if (ferror(ROBOTtxt)) {
perror("an error has occured");
exit(-1);
}
fclose(ROBOTtxt);
}
Your function loading_Profiles() written like this doesnt accept any parameters but you pass an array in the main function. You should rewrite the declaration as
"void loading_Profiles(Robot_t arr_name[])"
In the main function you should pass an argument only by its name. So instead of this:
"loading_Profiles(Robot_t RobotInfo[]);"
just pass:
"loading_Profiles(RobotInfo);"
There were a number of errors in your code, I'll paste my commented solution below, but for reference:
in the loading_Profiles prototype you weren't specifying a parameter
in the main, you were calling the function uncorrectly
inside the loading_Profiles implementation, you were trying to work on a local array, and not the one passed as an argument.
Also, sometimes you were using 50, sometimes 5? Which is it?
Here's the code, tested using a file generated on Mockaroo.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
typedef struct
{
int Robot_Number;
char Robot_Name[30];
int Year_Manufacturer;
float Top_Speed;
float Mass;
float Best_Score;
} Robot_t;
void loading_Profiles(Robot_t RobotInfo[]); // added parameter to prototype
int main()
{
Robot_t RobotInfo[50]; // 50 instead of 5
loading_Profiles(RobotInfo); // simply pass your variable
int i;
for (i = 0; i < 50; i++) {
printf("%d\t\t%s\t\t%d\t\t\t%.2f\t\t%.2f\t\t%.2f\n",
RobotInfo[i].Robot_Number, RobotInfo[i].Robot_Name,
RobotInfo[i].Year_Manufacturer, RobotInfo[i].Top_Speed,
RobotInfo[i].Mass, RobotInfo[i].Best_Score);
}
return 0;
}
void loading_Profiles(Robot_t RobotInfo[]) // added parameter
{
int Counter = 0;
int i;
FILE *ROBOTtxt = fopen("Robot.txt", "r");
//Robot_t RobotInfo[5]; // removed, work on the array passed as argument, not a local one
if (ROBOTtxt == NULL) {
perror("an error occured during the loading of the file\n");
exit(-1);
}
for (i = 0; i < 50; i++) {
char LineNumber[100] = "";
fgets(LineNumber, 100, ROBOTtxt);
sscanf(LineNumber, "%d %s %d %f %f %f",
&RobotInfo[i].Robot_Number,
RobotInfo[i].Robot_Name,
&RobotInfo[i].Year_Manufacturer,
&RobotInfo[i].Top_Speed,
&RobotInfo[i].Mass,
&RobotInfo[i].Best_Score);
Counter++;
if (feof(ROBOTtxt)) {
break;
}
}
if (ferror(ROBOTtxt)) {
perror("an error has occured");
exit(-1);
}
fclose(ROBOTtxt);
}
Let me know if it works
While declaring parameter for the function you need to specify variable type as structure and create an array of structure type.
void loading_Profiles(Robot_t RobotInfo[]) // added parameter

when compiling I get this error, I do not know what is wrong

I'm passing a matrix to a text file
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int llenarMatriz() {
int matriz[3][3]={1,2,3,4,5,6,7,8,9};
return matriz[3][3];
}
void guardarMatriz(int matriz[3][3]) {
char direccion[]="C:\\Users\\Usuario\\Desktop\\DIBU.txt";
FILE *archivo = fopen(direccion, "w");
if (archivo == NULL) {
exit(EXIT_FAILURE);
}
char linea[20];
sprintf(linea, "%d %d\n", 3, 3);
fputs(linea, archivo);
for (int i = 0; i < 3; i++) {
linea[0] = '\0';
for (int j = 0; j < 3; j++){
char buffer[10];
sprintf(buffer, "%d ", matriz[3][3]);
strcat(linea, buffer);
}
int len = strlen(linea);
linea[len - 1] = '\n';
fputs(linea,archivo);
}
fclose(archivo);
}
int main() {
llenarMatriz();
guardarMatriz(int matriz[3][3]);
system("pause");
return 0;
}
Error message;
In function 'main':
error: expected expression before 'int'
guardarMatriz(int matriz[3][3]);
You have two problems in your code. First you don't initialize a 2-D array correctly. It should look like this:
int matriz[3][3]={{1,2,3},{4,5,6},{7,8,9}};
second, you don't pass a type name to the function call to declare your variable, so it should look like this:
int matriz[3][3];
llenarMatriz();
guardarMatriz(matriz);
guardarMatriz(int matriz[3][3]);
Don't include the type and the dimensions when passing parameters to a function.
Also, when you call a function returning something, you should use the correct type (an int is not able to return a 2D array of int), and you must store the return somewhere.
In this case you can return a compound literal:
void *llenarMatriz(void)
{
return (int [][3]){{1,2,3},{4,5,6},{7,8,9}};
}
and in main:
int main(void) /* void is the correct argument for `main` */
{
int (*matriz)[3] = llenarMatriz(); /* A pointer to an array of int 3 */
guardarMatriz(matriz);
system("pause");
return 0;
}
If you don't want to declare the array inside main you can use the result of the first function as the argument of the second one:
guardarMatriz(llenarMatriz());
or you can pass the compound literal directly:
guardarMatriz((int [][3]){{1,2,3},{4,5,6},{7,8,9}});

How to return an array from function to main [duplicate]

This question already has answers here:
Returning an array using C
(8 answers)
Closed 6 years ago.
I have to use the function to open a file, read it, save the first value as the number of following elements (dimension) and the other values in the seq[] array.
I don't know how to return both dimension and seq[] in the main; I need it because I have to use these values in other functions. As the code shows, the function returns the dimension (dim), but I don't know how to return the array.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int leggiSequenza(char *nomeFile, int *seq) {
FILE *in;
int i;
int dim;
if((in = fopen(nomeFile, "r"))==NULL) {
printf("Error.\n");
return -1;
}
fscanf(in, "%d", &(dim));
printf("Find %d values.\n", dim);
if(dim < 0) {
printf("Errore: negative value.\n");
return -1;
}
seq = (int*) malloc(dim*sizeof(int));
i=0;
while(!feof(in) && i<(dim)) {
fscanf(in, "%d", &seq[i]);
i++;
}
for(i=0; i<(dim); i++) {
printf("Value in position number %d: %d.\n", i+1, seq[i]);
}
free(seq);
fclose(in);
return dim;
}
int main(int argc, char* argv[]) {
int letturaFile;
char nomeFile[200];
int *dimensione;
printf("Insert file name:\n");
scanf("%s", nomeFile);
printf("\n");
letturaFile = leggiSequenza(nomeFile, dimensione);
dimensione = &letturaFile;
printf("dimension = %d\n", *dimensione);
return 0;
}
I think the focus of the problem is *seq; I have to return two values (dimension and array). Moreover, I can't edit the parameters of the function.
I think my question is different from this because in my function there is a parameter with a pointer, and the function hasn't got a pointer...
Change the function to take the array pointer by pointer:
int leggiSequenza(char *nomeFile, int **seq);
// ^^^^^^^^^
Then call it with the address of your variable:
leggiSequenza(nomeFile, &dimensione);
// ^^^^^^^^^^^
Inside the function definition, change the details around like so:
int leggiSequenza(char *nomeFile, int **seq) {
// ...
int *local_seq = malloc(dim*sizeof(int));
// use local_seq in place of seq
// free(local_seq); // delete ...
*seq = localsec; // ... and replace with this
return dim;
}
Finally, the caller needs to free the array:
free(dimensione);
Update: Since you've re-asked your question: Pre-allocate the memory at the call site:
int * p = malloc(200 * sizeof(int));
int dim = leggiSequenza(filename, p);
// ...
free(p);
Simply your function should have this signature
int leggiSequenza(char *nomeFile, int **seq)
and when passing the parameter to it you should do
letturaFile = leggiSequenza(nomeFile, &dimensione);
that way, you'll have both things.
Also, everywhere in your function where you have just seq , you need to add *seq so you can dereference the pointer.
Hope this helps!
Do the alloction of the array in the main function
int *dimensione; = (int*) malloc(200*sizeof(int));
then delete this line
free(seq);
and you should have the data in the array in the main function.

Why can't I call my function(C)?

This is part of a program where I call a function that reads components from a ".dat" file and save the input to members of a Struct. When I try calling the function from my main.c it gives various errors depending on what I try. Most notably: conflicting types of 'ReadFile' and too few arguments to function 'ReadFile'. I also get a warning "passing argument from 'ReadFile' makes integer from pointer without cast" and some infos.
This is main.c
#include "MyData.h"
#include "NodalA.h"
#include "FileHandling.h"
#include <stdio.h>
#include "windows.h"
int main(){
ComponentType *CircuitData;
int numComp = 6;
int numEl = 0;
int numNodes = 0;
CircuitData = malloc((numComp)*sizeof(ComponentType));
ReadFile(CircuitData, &numEl, &numNodes);
return 0;
}
This is FileHandling.c:
#include "FileHandling.h"
#include "stdio.h"
void ReadFile(ComponentType *CircuitData, int *numEl, int *numNodes){
numEl = 0;
numNodes = 0;
int index = 0;
FILE *data;
data = fopen("mydata.dat", "r");
if (data == NULL){
printf("Error: \"mydata.dat\" could not be opened");
}
else {
while(!feof(data)){
fscanf(data, "%s, %s, %s, %f", CircuitData[index].name, CircuitData[index].node1, CircuitData[index].node2, CircuitData[index].value);
*CircuitData[index].node1 = extractInteger(CircuitData[index].node1);
*CircuitData[index].node2 = extractInteger(CircuitData[index].node2);
if(*CircuitData[index].node1 > *numNodes)
*numNodes = *CircuitData[index].node1;
if(*CircuitData[index].node2 > *numNodes)
*numNodes = *CircuitData[index].node2;
numEl++;
index++;
}
}
fclose(data);
}
And this is MyData.h
#ifndef MYDATA_H_
#define MYDATA_H_
typedef struct Comp{
char name[5]; //Name of circuit component
char node1[5], node2[5]; //2 nodes
float value[5]; //value
}ComponentType;
#endif /* MYDATA_H_ */
Any help would be appreciated. There are more code but I think this is the most important part.
The ReadFile function name used in the program is the same as a ReadFile function in "windows.h". The error "too few arguments to function 'ReadFile'" is most likely caused by the program trying to call the the function from windows with the wrong arguments. Removing "windows.h" or renaming the function ReadFile to something else solves the problem.

C - Call a function

I want to get a value from a function in other function i think i have to call a function in other function, then call it on main, but how?
void funcA(PEOPLE people[], int *total)
{
FILE *fp;
char line[100];
fp = fopen("example.txt", "r");
if (fp == NULL) {
exit(1);
}
else {
fgets(line, 100, fp); //get a number from the txt
total = atoi(line); //convert to int
}
}
void funcB(PEOPLE people[], int *total)
{
int i;
for (i = 0; i < total; i++) {
printf("%s\n", people[i].name);
}
funcA(people, &total);
}
void main()
{
PEOPLE people[100];
int *total;
funcB(people, &total);
}
What i'm doing wrong? I need the value from total to do cicle for;
First, you should call funcA from funcB like this:
funcA(people, total);
Then, if I understand you correctly, you want to return a value from your function(s). You can do it like this:
int funcA(PEOPLE people[], int *total){
int ret;
// set ret to desired value
return ret;
}
...
int value = funcA(people, total);
After sorting this out, you need to initialize your variables correctly, sort out the naming discrepancies (linha vs line, PEOPLE vs PERSON) and all other issues noted by others.
There are numerous problems here (total is a pointer, for loop on the pointer, never initialized to anything, etc etc).
To answer your question, functions have return types:
int foo(void) {
return 3;
}
int main(int argc, char**argv) {
printf("Foo returned %d\n", foo());
return 0;
}
In this case foo returns int. You return values with the return keyword.
You can also return data in pointers:
void foo(int* c) {
*c = 3;
}
int main(int argc, char**argv) {
int h;
foo(&h);
printf("Foo returned %d\n", h);
return 0;
}
This is helpful if you have multiple values to return.
Oh boy !
First what You are doing right or at least it seems so. You are drawing attention and get points for upvotes, despite the fact, that the code looks like typed in directly to the editor box on the Stackoverflow and never checked with any compiler. Good job :)
Now what's wrong. The list is long but some tips
void main()
{
PERSON person[100];
int *total;
funcB(people, &total);
}
void funcB(PEOPLE people[], int *total);
It would be nice if You showed us the definitions of (probably) structs PEOPLE and PERSON.
In the code we can see, there is no definition of people - the variable you pass to funcB.
You define a pointer to int - total and don't initialize it. Then You pass an address of that pointer to funcB which takes int* not int** as a second argument. Those types are not compatible.
void funcB(PEOPLE people[], int *total)
{
int i;
for (i = 0; i < total; i++) {
printf("%s\n", people[i].name);
}
funcA(people, &total);
}
void funcA(PEOPLE people[], int *total)
You use a pointer in the loop condition instead of the value pointed too. There is no value, because You didn't initialize the pointer in main, but here You have incompatible types in the condition. You pass an address of the pointer to funcA instead of the pointer, like in main.
void funcA(PEOPLE people[], int *total)
{
FILE *fp;
char line[100];
fp = fopen("example.txt", "r");
if (fp == NULL) {
exit(1);
}
else {
fgets(line, 100, fp); //get a number from the txt
total = atoi(linha); //convert to int
}
}
You use an undefined symbol 'linha' - I guess it's a misspelling of 'line'. Then You assign an int to a pointer instead of an int pointed to by that pointer.
Check these:
exit() function exited from your program, not only from function. You can use return; to return from the function.
total is not initialized when you use that. Use funcA(people, &total); line before the for loop in your function funcB.

Resources