Compile time error when using struct in other c file - c

I am using a structure that I defined in main.h and now using it in stack.c. In my main.h I have defined struct details and struct library. When I access them in stack.c I get the following error. When I am running a single main.c file then it's having no issues, so, I assume the issue lies in the stack.c or stack.h file.
Undefined symbols for architecture x86_64:
"_details", referenced from:
_main in main.o
_library_details in main.o
_push in stack.o
(maybe you meant: _library_details)
"_library", referenced from:
_main in main.o
_library_details in main.o
_push in stack.o
(maybe you meant: _library_details)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation
Here are my code snippets:
main.c
// write code below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
void library_details(void);
FILE *fp;
int choice, indexer = 1;
//details_struct details[maxsize];
//library_struct library[maxsize];
int main(void)
{
// library = malloc(sizeof(library_struct) * 2);
fp = fopen("input.txt","r");
library_details();
for (int i = 1; i < indexer; i++)
{
if(library[i].type == is_book)
{
printf("Item %i is book: %s with %i pages\n", i, details[i].title, details[i].pages);
}
else if(library[i].type == is_article)
{
printf("Item %i is article: %s with %i pages\n", i, details[i].title, details[i].pages);
}
}
fclose(fp);
//free(library);
return 0;
}
main.h
#ifndef __MAIN_H_
#define __MAIN_H_
enum book_type {is_book, is_article};
typedef struct library_struct
{
enum book_type type;
void *item;
}library_struct;
typedef struct details_struct
{
char title[50];
int pages;
}details_struct;
// external variables
extern int choice, indexer;
extern details_struct details[100];
extern library_struct library[100];
// library details
void library_details(void);
#endif // __MAIN_H_
stack.c
// stack.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
#include "main.h"
//functions declarations
void push(void);
stack books_stack[100];
int top = 0;
int stack_main(void)
{
return 0;
}
void push()
{
if(top >= 99)
{
printf("Stack Overflow\n");
exit(-1);
}
else
{
if(library[top].type == is_book)
{
strcpy(books_stack[top].s_title, details[top].title);
books_stack[top].s_pages = details[top].pages;
}
}
}
stack.h
#ifndef __STACK_H_
#define __STACK_H_
typedef struct stack
{
char s_title[50];
int s_pages;
}stack;
// functions declaration
void push();
#endif // __STACK_H_
Is there any issue with struct declarations?

Haven't used C in a while so I can't straight answer your question, but I made your code compile. However the compiled program has a C runtime abort. (Potentially some exception or something...) Examine this and consider the diff... in h you never instantiate, you declare, in c you instantiate your declaration. I don't know why you were doing extern + trying to instantiate... The other answers noted a most of the areas I messed with.
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
FILE *fp;
int choice, indexer = 1;
int maxsize = 50;
details_struct details[100];
library_struct library[100];
void library_details(void)
{
return;
}
int main(void)
{
// library = malloc(sizeof(library_struct) * 2);
fp = fopen("input.txt","r");
library_details();
for (int i = 1; i < indexer; i++)
{
if(library[i].type == is_book)
{
printf("Item %i is book: %s with %i pages\n", i, details[i].title, details[i].pages);
}
else if(library[i].type == is_article)
{
printf("Item %i is article: %s with %i pages\n", i, details[i].title, details[i].pages);
}
}
fclose(fp);
//free(library);
return 0;
}
main.h
#ifndef __MAIN_H_
#define __MAIN_H_
enum book_type {is_book, is_article};
typedef struct library_struct
{
enum book_type type;
void *item;
} library_struct;
typedef struct details_struct
{
char title[50];
int pages;
} details_struct;
// external variables
extern int choice, indexer;
details_struct details[];
library_struct library[];
// library details
void library_details(void);
#endif // __MAIN_H_
stack.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stack.h"
//functions declarations
void push(void);
stack books_stack[100];
int top = 0;
int stack_main(void)
{
return 0;
}
void push() {
if (top >= 99) {
printf("Stack Overflow\n");
exit(-1);
} else {
if (library[top].type == is_book) {
strcpy(books_stack[top].s_title, details[top].title);
books_stack[top].s_pages = details[top].pages;
}
}
stack.h
#ifndef __STACK_H_
#define __STACK_H_
#include "main.h"
typedef struct stack
{
char s_title[50];
int s_pages;
} stack;
// functions declaration
void push();
#endif // __STACK_H_
}

library an library_details are not exist in your code
You declare the function in main.h, but is not in in main.c
And, with library[], you are using but is not declared

You seem to have commented out the variable declarations:
//details_struct details[maxsize];
//library_struct library[maxsize];
So, neither details nor library are defined, and this is what the compiler is complaining about.

Related

Code::Blocks : Functions (and functions prototype) with the pointer FILE parameter get an error

So I was doing some basic C then I'm blocked.
I wanted to count lines in a file. Function and prototype function are in .c (for the function) and in .h (for the prototype function), the problem is I get errors
Note : I use the compiler GNU GCC C++ 14 ISO
From Function.c :
#include "Functions.h"
int FileLineCount(FILE *file)
{
rewind(file);
int iCount = 0;
char string[MAX_CHARACTER_SIZE] = "";
while((fgets(string, MAX_CHARACTER_SIZE, file) != NULL))
{
iCount++;
}
return iCount;
}
From Function.h :
#ifndef __FUNCTIONS_INCLUDED__
#define __FONCTIONS_INCLUDED__
int FileLineCount(FILE *file);
#endif
From the main.c :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "Functions.h"
#define MAX_CHARACTER_SIZE 256
int main()
{
FILE *WordsFile = NULL;
const char strWorldFileName[] = "RandomWords.txt";
WordsFile = fopen(strWorldFileName, "r");
if(WordsFile == NULL)
{
printf("Error ! Impossible to open the file %s\n", strWorldFileName);
printf("Verify if this .txt file is in the folder where the file main.c is in it\n");
return EXIT_FAILURE;
}
printf("Line count : %i\n\n", FileLineCount(WordsFile));
}
Here is the error from the compiler :
error: unknown type name 'FILE'
error: unknown type name 'FILE'
#include <stdio.h>
in your Functions.h file
and fix this to be the same 'functions' and 'fonctions'
#ifndef __FUNCTIONS_INCLUDED__
#define __FONCTIONS_INCLUDED__

C - Pass struct by reference

I am trying to pass a structure by reference in C so that I can modify the values from within the function. This is the code I have so far, but it produces some warnings and one error.
main.c
#include <stdio.h>
#include "myfunctions.h"
#include "structures.h"
int main(int argc, char const *argv[] {
struct MyStruct data;
data.value = 6;
printf("Before change: %d\n", data.value);
changeData(data);
printf("After change: %d\n", data.value);
}
myfunctions.c
#include "structures.h"
void changeData(MyStruct data) {
data.value = 7;
}
myfunctions.h
#ifndef MyStruct
#define MyStruct
void changeData(MyStruct data);
#endif
structures.h
typedef struct {
int value;
} MyStruct;
Errors Produced
In file included from main.c:2:0:
myfunctions.h:4:1: warning: parameter names (without types) in function declaration
void changeData(MyStruct data);
^
In file included from main.c:3:0:
structures.h:5:1: warning: unnamed struct/union that defines no instances
} MyStruct;
^
main.c: In function ‘main’:
main.c:9:5: error: ‘data’ undeclared (first use in this function)
data.value = 6;
^
main.c:9:5: note: each undeclared identifier is reported only once for each function it appears in
That's all caused by
#define MyStruct
With this line, you've defined MyStruct as a macro that expands to nothing. I.e. you've effectively removed all occurrences of MyStruct in the following code, which is why the compiler is so confused about seeing things like
typedef struct {
int value;
} ;
or
void changeData( data);
To fix this, use
#ifndef MYFUNCTIONS_H_
#define MYFUNCTIONS_H_
instead. (This is the reason why we use ALL_UPPERCASE names for macros: To avoid accidental name clashes with normal identifiers.)
applying all my comments and elimination of the unnecessary 'typedef', and placing it all in one file ( Note: there is no problem with extracting the various files), results in the following code:
#ifndef STRUCTURES_H
#define STRUCTURES_H
struct MyStruct
{
int value;
};
#endif // STRUCTURES_H
#ifndef MYFUNCTIONS_H
#define MYFUNCTIONS_H
void changeData( struct MyStruct *data);
#endif // MYFUNCTIONS_H
#include <stdio.h>
//#include "myfunctions.h"
//#include "structures.h"
int main( void )
{
struct MyStruct data;
data.value = 6;
printf("Before change: %d\n", data.value);
changeData(&data);
printf("After change: %d\n", data.value);
} // end function: main
//#include "structures.h"
void changeData( struct MyStruct *data)
{
data->value = 7;
} // end function: changeData
which cleanly compiles and does do the desired operation

C: Include a file which includes a file that also needs to be included in the main program

I have a header file (generalfunctions.h):
#ifndef GENERALFUNCTIONS_H
#define GENERALFUNCTIONS_H
//functionsdeclartion for example
int getInt(char* text);
#endif /* GENERALFUNCTIONS_H */
and a C file generalfunctions.c where I include this headerfile (so I can use some of the functions within each other and don't have bother with their order) and code out the functions.
generalfunctions.c:
#include "generalfunctions.h"
#include <stdlib.h>
#include <stdio.h>
//functions implentaion for example
int getInt(char* text){
int i;
printf("%s\n", text);
if(scanf("%d", &i)==EOF){
printf("INT_ERROR\n");
exit(1);
}
while (fgetc(stdin) != '\n');
return i;
}
//...
Now I need some of these functions in a file called project_objects.c that together with project_objects.h defines a couple of structs, unions, variables and functions with these things I need for my project.
project_objects.h:
#ifndef POINT_H
#define POINT_H
typedef struct point{
int x;
int y;
} point;
point create_point(void);
void print_point(point *p);
//...
#endif /* POINT_H */
project_objects.c:
#include <stdlib.h>
#include <stdio.h>
#include "project_objects.h"
#include "generalfunctions.h"
point create_point(void){
point p;
p.x=getInt("Give my a x");
p.y=getInt("Give my a y");
return p;
}
void print_point(point *p){
printf("x: %d\n", p->x);
printf("y: %d\n", p->y);
}
//..
However I also need some of the functions described in generalfunctions.h directly in my main program:
#include "generalfunctions.c"
#include "project_objects.c"
#include <stdlib.h>
#include <stdio.h>
int main(void){
int i=getInt("How many points would you like to create?");
while(i<1){
i=getInt("Cannot create a negative number of points. How many points would you like to create?");
}
point pointarray[i];
for(int j=0; j<i; j++){
pointarray[j]=create_point();
}
for(int k=0; k<i; k++){
printf("Point %d:\n", k+1);
print_point(pointarray+k);
}
return EXIT_SUCCESS;
}
This seems to work. If I just include the h-files than I get the error that getInt() isn't defined when I link. And before when I included the C file for general functions in project_object.c I got errors for duplication. But now the files seem more dependent on each other than I planned. I also don't understand why this works.
Do not include .c-files. Write function protytypes in .h-files and include them.
project_object.h
typedef int faa;
foo.h
include "project_object.h"
faa foo( faa x ); // prototype for function "foo"
foo.c
#include "foo.h"
faa foo( faa x ) // implementation of function "foo"
{
return x + 666;
}
main.c
#include "project_object.h"
#include "foo.h" // include .h-file with prototype of function "foo"
int main( void )
{
faa x;
x = foo(0); // call function "foo"
return 0;
}

Header file with a struct and function prototypes using the keyword "extern"

I'm trying to define a struct in a header file with function prototypes that take pointer to that struct as a parameter.
#ifndef _GETDATA
#define _GETDATA
struct PERSONDATA{
char name[20];
double age,mass;
};
typedef struct PERSONDATA person;
extern void getData(person *);
extern void getName(char *,int);
#endif
The getData.c file is defined as such;
#include <stdio.h>
void getData(person *ptr)
{
printf("Enter name: ");
getName(ptr->name,sizeof(ptr->name));
}
and the getName.c file is defined as:
#include <stdio.h>
void getName(char *ptrName, int varSize)
{
int i=0;
do
{
*(ptrName++) = getchar();
++i;
if(i==varSize) printf("array full, EXITING!\n");
}while(*(ptrName-1)!='\n' && i<varSize);
}
Lastly, the main function was:
#include <stdio.h>
#include "GETDATA.h"
int main(int argc, char **argv)
{
person human1;
printf("hello, world!\n\n");
getData(&human1);
return 0;
}
On compiling the program, I get the following error:
***C:/Users/Shoaib.Shoaib-PC/Google Drive/C workspace/C workspace codelite/StructPointerExample/getData.c:2:14: error: unknown type name 'person',
void getData(person *ptr)***
Could some one please help me out here, any help is greatly appreciated!
You should include the header file in ALL files using the declared types, not just in the main file.

how do i use vars, functions and structs in other files?

In timer.c I have
typedef struct Timer {
int startTicks;
int pausedTicks;
int paused;
int started;
} Timer;
void Init( Timer *t )
{
t->startTicks = 0;
t->pausedTicks = 0;
t->paused = 0;
t->started = 0;
}
What do i need to do in main.c to make use of this struct and functions in that file?
In general, .c files contain definitions and .h files contain declarations. A better approach would be to keep your definitions in a header:
//timer.h
#ifndef TIMER_H //include guard
#define TIMER_H
typedef struct Timer { //struct declaration
int startTicks;
int pausedTicks;
int paused;
int started;
} Timer;
void Init( Timer *t ); //method declaration
#endif
//timer.c
#include "timer.h"
void Init( Timer *t ) //method definition
{
t->startTicks = 0;
t->pausedTicks = 0;
t->paused = 0;
t->started = 0;
}
//main.c
#include "timer.h" //include declarations
int main()
{
Timer* t = malloc(sizeof(Timer));
Init(t);
free(t);
return 0;
}
Learn to use header files (usually named *.h) and #include them.
Learn how to compile a program with several compilation units, e.g. with a Makefile.
Don't forget to enable all warnings and debugging information (with GCC, that means gcc -g -Wall, i.e. CFLAGS=-g -Wall in your Makefile).

Resources