I am new to C programming. When I include the blank.h file into the Test.c file the program will not compile, however when I include blank.c file into the Test.c file it compiles fine. Below is the source for all the .c and .h files. Im using gcc as my compiler, and I have a feeling I need to do some sort of linking with it? Any help would be great thanks!
This is the Test.c source
#include <stdio.h>
#include "blank.h"
#include "boolean.h"
int main()
{
bool result = blank("");
printf("%d\n", result);
return 0;
}
This is the blank.h source
// Header file for blank function
bool blank(char string[]);
This is the blank.c source
#include "boolean.h"
#include "blank.h"
#include <regex.h>
bool blank(char string[])
{
regex_t regex_blank;
int blank = regcomp(®ex_blank, "[:blank:]", 0);
blank = regexec(®ex_blank, string, 0, NULL, 0);
if ( string == NULL || blank == 1 )
return true;
else
return false;
}
and finally the boolean.h
// Boolean
// Define true
#ifndef true
#define true 1
#endif
// Define false
#ifndef false
#define false 0
#endif
typedef int bool;
Ok, so I tried the source code you provided. There were a couple problems. Here are the exact steps of how I built, what I fixed. See if this works for you:
Created 4 files in a folder: Test.c, blank.c, blank.h and boolean.h
Copied code over.
From the shell ran:
gcc Test.c blank.c -o b
Output:
In file included from Test.c:2:0:
blank.h:3:1: error: unknown type name ‘bool’
blank.c: In function ‘blank’:
blank.c:11:46: error: ‘NULL’ undeclared (first use in this function)
blank.c:11:46: note: each undeclared identifier is reported only once for each function it appears in
To fix the first error:
In blank.h added this on top: #include "boolean.h"
To fix the second error:
In blank.c added this after the other includes: #include <stdlib.h>
Once again the terminal ran:
gcc Test.c blank.c -o b
then from the terminal ran ./b and it prints 1.
I suppose you are running GCC manually otherwise you wouldn't have that problem.
you can run GCC for each .c file manually or you can just run it for them all togather.
gcc *.c
if you do the later, you should not run into linker errors.
You forgot include guards:
blank.h:
#ifndef BLANK_H_INCLUDED
#define BLANK_H_INCLUDED
bool blank(char string[]);
#endif
These include guards prevent the contents of the header file being redefined each time a source file includes it. Make sure to do this for boolean.h too.
You need to include boolean.h in blank.h,
// Header file for blank function
#include "boolean.h"
bool blank(char string[]);
or you need to include it befor blank.h in Test.c, otherwise the compiler doesn't know the type bool in the declaration of blank.
Apart from that, the advice to always use include guards is good and should be followed.
Once removing the #include "blank.h" from Test.c and running gcc Test.c blank.c it compiled fine. Thank you for the advice on the include guards, and doing gcc Text.c blank.c
Related
I have two files main.c and header.c.
main.c has some macro STR who value I want to define conditionally according to some #define in the file.
Case 1:
When I include header.c in main.c file, the program is working fine as shown below:
main.c
#include<stdio.h>
#define _flag_b
#include "header.c"
void main(){
printf("%s", STR);
}
header.c
#ifndef _flag_a
#define STR "flag a is activated.\n"
#endif
#ifndef _flag_b
#define STR "flag b is activated.\n"
#endif
Compilation
anupam#g3:~/Desktop/OS 2020/so$ gcc main.c
anupam#g3:~/Desktop/OS 2020/so$ ./a.out
flag a is activated.
Case 2:
But for some reason, I want to include header.c in the compile command and not inside main.c. Which is creating this issue for me as shown below:
main.c
#include<stdio.h>
#define _flag_b
// #include "header.c"
void main(){
printf("%s", STR);
}
header.c
#ifndef _flag_a
#define STR "flag a is activated.\n"
#endif
#ifndef _flag_b
#define STR "flag b is activated.\n"
#endif
Compilation
anupam#g3:~/Desktop/OS 2020/so$ gcc main.c header.c
main.c: In function ‘main’:
main.c:7:15: error: ‘STR’ undeclared (first use in this function)
7 | printf("%s", STR);
| ^~~
main.c:7:15: note: each undeclared identifier is reported only once for each function it appears in
header.c:6: warning: "STR" redefined
6 | #define STR "flag b is activated.\n"
|
header.c:2: note: this is the location of the previous definition
2 | #define STR "flag a is activated.\n"
|
I have done a lot of research on this issue, and able to understand why the problem is arising. But I am not able to solve this issue.
Please help me in understanding this problem better and suggest some solutions to this. Also help me in rephrasing the problem.
#define defines a macro for a preprocessor - it means that before compilation, every instance of defined macro (after its definition) is replaced, in Your case after #define STR ... every instance of STR is replaced with specified constant. More about macros here
#include just copy a file and paste it in specified place. More about headers here
First example works because you included your header and code looks like this:
/*
stuff included by stdio.h
*/
int main(void) {
printf("%s", "flag a is activated.\n");
}
And it can compile easily. But in the second example you try to compile every file separately, so the first file looks like this:
/*
stuff included by stdio.h
*/
int main(void) {
printf("%s", STR); //preprocessor doesn't recognise STR as a macro
}
And the second file is empty. So now the compiler tries to compile it and it doesn't know what STR is, so you have an error.
If you want to keep it as a #define then you need to include the header.
You can read more about preprocessing here. If you want to see the output of preprocessor then you need to use a -E flag, for example: gcc main.c -E -o mainPreprocessed.c
Please, next time include code as a text, not an image - it will be easier for people to answer.
One more thing: *.c files are for code (that you add in your g++ command) and *.h files are for headers (that you include with #include).
I work on a project that has multiple c files. Each c file has its own header. Now I want to put all c files together.
As a preperation I have tried the following thing:
This would be my example c-code (function.c):
#include <stdio.h>
#include "function.h"
void output()
{
printf("Thats a text\n");
}
Thats the associated header file (function.h):
//header function.h
#ifndef FUNCTION_H_
#define FUNCTION_H_
#endif // FUNCTION_H_
And thats my main.c:
#include "function.h"
int main()
{
output();
return 0;
}
I would expect the following output:
"Thats a text"
But I only receive following error:
undefined reference to 'output'
What am I doing wrong here?
Thanks a lot!
You need the prototype for output function in your header so that it's visible in other module(s).
//header function.h
#ifndef FUNCTION_H_
#define FUNCTION_H_
void output(void);
#endif // FUNCTION_H_
And you need to link the module (source file function.c) in order to actually provide the definition of output that your main module uses.
For example, you can directly compile them together with:
gcc main.c function.c -o my_out
You may also want to look at Makefiles as well.
Your header should be
//header function.h
#ifndef FUNCTION_H_
#define FUNCTION_H_
void output();
#endif // FUNCTION_H_
compile like this:
(actual flags may depend on compiler used)
cc -c main.c
(creates main.o)
cc -c function.c
(creates function.o)
cc main.o function.o
(creates a.out or whatever your system default is)
...or as someone else mentioned:
cc main.c function.c
(does it all)
Coming up with errors for undefined references in main.c. This is because I have several files in this fashion:
main.c
{
#include "somefile.h"
somfunct() <--- undefined reference error
}
somefile.h
{
somefunct() declaration
...
}
somefile.c
{
#include "somefile.h"
somefunct() definition
...
}
I am trying to use proper organization in that I use only declarations in the header files and define them in a separate file. After splitting up my code I get the undefined reference error because there is no link between somefile.h and somefile.c. Even though main.c includes the somefile.h header file, there is nothing in somefile.h that explicitly mentions somefile.c, so my functions are only partially defined. What is the proper way to take care of this problem? Many thanks. I hope this is clear let me know if not.
Here's a complete and working example of your goal.
main.c
#include "somefile.h"
int main() {
somefunc();
return 0;
}
somefile.h
#ifndef RHURAC_SOMEFILE_H
#define RHURAC_SOMEFILE_H
void somefunc();
#endif
somefile.c
#include <stdio.h>
#include "somefile.h"
void somefunc() {
printf("hello\n");
}
example build ( gcc )
gcc main.c somefile.c -o main
output
$ ./main
hello
This is my code. I have file1.c and file2.c. I want to call the MESSAGE from file2.c but I can't seem to do it. I am newbie in C so I really don't know what to do. I researched already but, I can't seem to find a specific answer. Thankyou.
#define MESSAGE "this is message!"
helloworld(){
printf("%s",MESSAGE);
getch();
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file2.c"
int main(void)
{
helloworld();
}
There are a few misconceptions you have: First of all the concept of "calling" a macro. It's not possible, even if a macro looks like a function it's not a function and macros are not actually handled by the compiler. Instead macros are part of a separate language that is handled by a preprocessor, which takes the source file and modifies it to generate a translation unit that the compiler sees. (For more information about the difference phases of "compilation" see e.g. this reference.)
The preprocessor does this by basically doing a search-replace in the input source file: When it sees a macro "invocation" it simply replaces that with the "body" of the macro. When it sees an #include directive, it preprocesses the file and then puts the content in place of the directive.
So in your code, when the preprocessor sees the macro MESSAGE it is literally replaced by "this is message!". The actual compiler doesn't see MESSAGE at all, it only sees the string literal.
Another misconception is how you use the #include directive. You should not use it to include source files. Instead you compile the source files separately (which creates object files) and then link the generated object files together with whatever libraries are needed to form the final executable.
To solve the problem of macros (and other declarations) being available to all source files, you use header files. These are like source files, but only contains declarations and macros. You then include the header file in both source files, and both source files will know about the declarations and macros available in the header file.
So in your case you should have three files: The main source file, the source file containing the function, and a header file containing the macro and the function declaration (also known as a prototype). Something like
Header file, e.g. header.h:
// First an include guard (see e.g. https://en.wikipedia.org/wiki/Include_guard)
#ifndef HEADER_H
#define HEADER_H
// Define the macro, if it needs to be used by all source files
// including this header file
#define MESSAGE "this is message!"
// Declare a function prototype so it can be used from other
// source files
void helloworld();
#endif
Main source file, e.g. main.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
int main(void)
{
// Use the macro
printf("From main, MESSAGE = %s\n", MESSAGE);
// Call the function from the other file
helloworld();
}
The other file, e.g. hello.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
void helloworld(void)
{
printf("Hello world!\n");
printf("From helloworld, MESSAGE = %s\n", MESSAGE);
}
Now, if you use a command-line compiler like gcc or clang then you can simply build it all by doing e.g.
$ gcc -Wall main.c hello.c -o myhello
That command will take the two source files, main.c and hello.c and run the preprocessor and compiler on them to generate (temporary) object files. These object files are then linked together with the standard C library to form the program myhello (that's what the option -o does, names the output file).
You can then run myhello:
$ ./myhello
From main, MESSAGE = this is message!
Hello world!
From helloworld, MESSAGE = this is message!
In your file1.c, MESSAGE is a preprocessor macro, which means the text MESSAGE will be replaced with the string "this is message!". It is not visible outside the file. This is because in C, translation units are the final inputs to the compiler, and thes translation units already have all of preprocessor macros replaced by the tokens of the corresponding argument.
If you want to have a common variable, you should declare the variable as extern in a .h header file, and then #include the file where you need to use it.
see Compiling multiple C files in a program
You have to put your #define in a .h file and include it in .c files where you want to use it.
You can write the files as below and compile the code as i mention in the following steps.
file1.h
#ifndef _FILE1_H
#define _FILE1_H
#define MESSAGE "this is message!"
extern void helloworld();
#endif
file1.c
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
file2.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
return 0;
}
For compiling,
gcc -Wall file1.c file2.c -o myprog
./myprog
Here is code try this:
In File1.C
#define FILE1_C
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
In File2.C
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
}
In File1.h
#ifdef FILE1_C
#define MESSAGE "this is message!"
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN helloword()
// File foo1.c :
#include <stdio.h> // once
void foo1(void);
void foo1(void){
puts("foo1");
}
// File foo2.c :
#include <stdio.h> // again
void foo2(void);
void foo2(void){
puts("foo2");
}
// File foomain.c :
#include <stdio.h> // yet again
void foo1(void); // again
void foo2(void); // again
int main(void){
foo1();
foo2();
puts("foomain");
return 0;
}
// create object files
gcc -fPIC foo1.c -o foo1.o // 1 stdio.h
gcc -fPIC foo2.c -o foo2.o // 1 stdio.h
// create shared library
gcc -fPIC -shared foo1.o foo2.o -o foo.so // foo.so contains stdio.h 2 times ?
// build entire program
gcc foo.so foomain.c -o foomain // foomain contains 1 stdio.h plus the 2 from foo.so ?
Why does the entire program contain 3 stdio.h ? Seems redundant, why not just 1 ? Shouldn't the compiler need only 1 ?
It makes sense for the object files to contain a prototype but why do they have to be specified again in foomain.c ? Shouldn't the compiler know they are already specified in foo.so ?
That's because each file is compiled separately, so each time the compiler should know the signatures of all functions used to perform compile-time checks. So, each file has to contain all declarations used, which are included by the preprocessor before the file is compiled.
If you look at the top of most header files they have an include guard to stop double inclusion.
#ifndef FOO
#define FOO
#endif
See Include Guard for more information.
The #include lines are not actually a part of the compiler, but the C preprocessor.
What the preprocessor does with #include lines is to actually include the file into the source, and creates a new temporary file containing the contents of your file with the #include line replaced by the contents of the file being included.
You don't actually need the include file at all, if all you are doing is calling functions. You might get warnings about the functions not being declared, but those can be adding the prototypes for those functions yourself. For example, in your main source file you only use puts, instead of including <stdio.h> you can add a prototype like this:
int puts(const char *s);
However, <stdio.h> also defines some structures (like the FILE structure) and declares some variables (like stdout) and if you use any of those you need the header file as well.
You can use include guards as #Jeff suggested or just put #pragma once at the top of each header.