Reading next line of a file with fscanf() - c

I am using two functions to read doubles(read_double) and integers(read_integer) from a file.
The file format is as follows excluding the characters in the ( )'s
12345678 (ID)
3.78 (GPA)
3 (Year)
20.5 (Age)
There are 5 of these entries in the file to be read.
#include <stdio.h>
double read_double(FILE *infile)
{
double double1=0.0;
fscanf(infile, "%lf",&double1);
return double1;
}
int read_integer(FILE *infile)
{
int int1=0;
fscanf(infile, "%d",&int1);
return int1;
}
int main(void)
{
FILE *inp,*outp;
double gpa1=0.0;
int id1=0;
inp=fopen("input.txt","r");
outp=fopen("output.txt","w");
id1=read_integer(inp);
gpa1=read_double(inp);
printf("%d, %.2lf",id1,gpa1);
return 0;
}
When this code runs it prints the Student ID which is 12345678, it then prints 1.00. This is due to it reading first the ID again.
How would I make this read the second line and return the GPA (3.78)
I need to split the program so that main is in one file, and the other functions are on another.
Note: I will have to do this 5 times. Also we have not "learned while statements or "gets()" so please try not to use these or more complex methods.

As per the comments, what you want is to split the program in library and main.
So, the library will have the two functions:
/* lib.c */
#include <stdio.h>
double read_double(FILE *infile)
{
double double1=0.0;
fscanf(infile, "%lf",&double1);
return double1;
}
int read_integer(FILE *infile)
{
int int1=0;
fscanf(infile, "%d",&int1);
return int1;
}
The header file will help programs that use your library know what to expect from the functions (what types should be used for their arguments and return values). It only contains prototypes, and not the actual function definitions:
/* lib.h */
#include <stdio.h>
double read_double(FILE *infile);
int read_integer(FILE *infile);
And main uses them:
/* main.c */
#include <stdio.h>
#include "lib.h" /* <== here! use the prototypes so
the compiler will know that
read_double returns double! */
int main(void)
{
FILE *inp;
double gpa1=0.0;
int id1=0;
inp=fopen("input.txt","r");
id1=read_integer(inp);
gpa1=read_double(inp);
printf("%d, %.2lf",id1,gpa1);
return 0;
}
And compile them:
gcc lib.c main.c -o program
Now, the input file is:
12345678
3.78
3
20.5
And we run the program:
./program
12345678, 3.78
Now, if we remove the #include "lib.h" from main
#include <stdio.h>
int main(void)
{
FILE *inp;
double gpa1=0.0;
int id1=0;
inp=fopen("input.txt","r");
id1=read_integer(inp);
gpa1=read_double(inp);
printf("%d, %.2lf",id1,gpa1);
return 0;
}
and compile it with optimization,
gcc -O3 lib.c main.c
Then the result is wrong:
./program
12345678, 1.0
because the compiler generated code assuming all functions return integers. And doubles and integers are represented in a totally different way, internally.

Related

How do I use values from a .h file for calculations in a .c file?

I'm trying to calculate values in rand.h:
#ifndef RAND_H_INCLUDED
#define RAND_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double rando()
{
srand(time(NULL));
double base=rand(); /*using base instead of time because of random generator using the built-in time function*/
double height[20];
double pressure[20];
/*random heights*/
int i;
for(i=0;i<20;i++){
height[i]=rand();
}
/*random pressures*/
int q;
for(q=0;q<20;q++){
pressure[q]=rand();
}
}
#endif // RAND_H_INCLUDED
And then use them for the calculations in main.c:
#include <stdio.h>
#include <stdlib.h>
#include "rand.h"
int main() /*table formatting testing*/
{
rando();
double base;
double height;
double pressure;
int hnum=sizeof(height)/sizeof(height[0]);
int pnum=sizeof(pressure)/sizeof(pressure[0]);
/*printing height*/
int hloop;
for (hloop=0;hloop<hnum;hloop++){
if (hloop==0){
printf(" %g",height[hloop]);
} else{
printf(" %g",height[hloop]);
}
}
/*printing time and pressure*/
printf("\n");
int ploop;
for (ploop=0;ploop<pnum;ploop++){
if (ploop==0){
printf("%g %g",base,pressure[ploop]);
} else{
printf(" %g",pressure[ploop]);
}
}
return 0;
}
However, I get multiple errors from rand.h and main.c. From rand.h I get the both pressure and height are set but not used, and that base is unused. From main.c I get a bunch of errors saying that pressure and height aren't arrays, pointers, or vectors. How do I use the values calculated in rand.h for the calculations in main.c. Note that the values must be calculated in rand.h then somehow transferred to main.c.
You seem to be under the impression that the variables base, height, and pressure in the rando function are the same ones in the main function. They are not. Variables declared in a function are local to that function.
This is why you're getting warnings that these variables in rando are not used, because they're not being read anywhere in this function.
The errors you get from the main function are because height and pressure are in fact not arrays:
double height;
double pressure;
You need to change rando to take a parameter for each of these three objects:
void rando(double *base, double *height, double *pressure)
Note also that the return type is changed to void because you're not actually returning anything. Then the body would have the following changes:
srand(time(NULL));
*base=rand(); // dereference the given pointer to change base in main
/*random heights*/
Then in main you would make this change:
double base;
double height[20];
double pressure[20];
rando(&base, height, pressure);
Note that you need to pass the address of base so that it can be changed. This is not needed on the two arrays as the names are converted to pointers when passed to the function.
On a separate note, it's not a good idea to have function definitions in a header file. If this header were to be included by more than one .c file, you would get errors about the function being defined multiple times.
The header should only contain a declaration:
#ifndef RAND_H_INCLUDED
#define RAND_H_INCLUDED
void rando(double *base, double *height, double *pressure);
#endif // RAND_H_INCLUDED
And the body of the function would be in a separate file, i.e. rand.c. Then you would compile both rand.c and main.c and link them.
First you shouldn't implement function in .h files, create a separate .c and define it in .h file to use it in an another .c by calling this .h file, it's more readable on large project.
Second point your function isn't returning anything it should be void rando() (It's not a function, it's called a procedure if I'm right on the English name).
And I guess your procedure is made to initialize some random data, so why do you call the function before you initialize the variable ?
The point is that your variable is not even global, so you should have parameter define for calling the function (since they are array you don't need to create pointer)
Try either make rando() of type void...
#ifndef RAND_H_INCLUDED
#define RAND_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void rando() //change type void
{
srand(time(NULL));
double base=rand(); /*using base instead of time because of random generator using the built-in time function*/
double height[20];
double pressure[20];
/*random heights*/
int i;
for(i=0;i<20;i++){
height[i]=rand();
}
/*random pressures*/
int q;
for(q=0;q<20;q++){
pressure[q]=rand();
}
}
#endif // RAND_H_INCLUDED
or, just write a return statement,
#ifndef RAND_H_INCLUDED
#define RAND_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double rando()
{
srand(time(NULL));
double base=rand(); /*using base instead of time because of random generator using the built-in time function*/
double height[20];
double pressure[20];
/*random heights*/
int i;
for(i=0;i<20;i++){
height[i]=rand();
}
/*random pressures*/
int q;
for(q=0;q<20;q++){
pressure[q]=rand();
}
return 0; //correction
}
#endif // RAND_H_INCLUDED
In rand.h declare a struct containing all of the values to be initialized by rando()
Define a structure of this type in main
Pass the address of this structure to rando()
In main(), use the values with the syntax structure.member
What's usually the suggested approach in C programming language is to put:
Function Declarations in HEADER (.h) files
Function Definitions in C (.c) files
So, I would have three files in your case:
main.c (with the main function)
rand.c (with rando function definition)
rand.h (with rando function header)
main.c
#include <stdio.h>
#include <stdlib.h>
#include "rand.h"
int main() /*table formatting testing*/
{
rando();
double base;
double height;
double pressure;
int hnum=sizeof(height)/sizeof(height[0]);
int pnum=sizeof(pressure)/sizeof(pressure[0]);
/*printing height*/
int hloop;
for (hloop=0;hloop<hnum;hloop++){
if (hloop==0){
printf(" %g",height[hloop]);
} else{
printf(" %g",height[hloop]);
}
}
/*printing time and pressure*/
printf("\n");
int ploop;
for (ploop=0;ploop<pnum;ploop++){
if (ploop==0){
printf("%g %g",base,pressure[ploop]);
} else{
printf(" %g",pressure[ploop]);
}
}
return 0;
}
rand.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "rand.h"
double rando()
{
srand(time(NULL));
double base=rand(); /*using base instead of time because of random generator using the built-in time function*/
double height[20];
double pressure[20];
/*random heights*/
int i;
for(i=0;i<20;i++){
height[i]=rand();
}
/*random pressures*/
int q;
for(q=0;q<20;q++){
pressure[q]=rand();
}
}
rand.h
#ifndef RAND_H_INCLUDED
#define RAND_H_INCLUDED
double rando();
#endif // RAND_H_INCLUDED
=======
After all these, you write a Makefile for your build process. But if you want to compile everything by hand, you can do:
$ gcc -c rand.c
$ gcc -c main.c
$ gcc rand.o main.o -o main
$ ./main
But, do keep in mind that your code does not compile. It has some errors (such us using pressure (or height) as a global array although it's just a local double variable inside main function.

Importing a C function

What's wrong with the following import statement? I feel like I'm screwing up something pretty basic here:
// main.c
#include <stdio.h>
#include "1_square.h"
int main(int argc, char *argv[]) {
int a=4;
int a_squared=square(a);
printf("Square of %d is %d\n", a, a_squared);
return 0;
}
// 1_square.h
int square(int num);
// 1_square.c
int square(int num) {
return num*num;
}
$ gcc 0_main.c -o 0_main && ./0_main
/usr/bin/ld: /tmp/cc6qVzAM.o: in function main': 0_main.c:(.text+0x20): undefined reference to square'
collect2: error: ld returned 1 exit status
Or does gcc need a reference to 1_square in order to build it?
You need to add the 1_square.c file to your build command:
gcc -o 0_main 0_main.c 1_square.c && ./0_main
You need the definition of the function as well as its declaration.
From the comments:
Why then does it need 1_square.c in the commandline and then also 1_square.h in the 0_main.c header?
Like John Bollinger points out in the comments, the only thing 1_square.h and 1_square.c have in common is their name, which isn't meaningful to the compiler. There's no inherent relationship between them as far as gcc is concerned.
Let's start by putting everything in one source file:
/** main.c */
#include <stdio.h>
int square( int num );
int main( int argc, char **argv )
{
int a = 4;
int a_squared = square( a );
printf( "Square of %d is %d\n", a, a_squared );
return 0;
}
int square( int num )
{
return num * num;
}
In C, a function must be declared before it is called in the source code; the declaration introduces the function name, its return type, and the number and types of its arguments. This will let the compiler verify that the function call is written correctly during translation and issue a diagnostic if it isn't, rather than waiting until runtime to throw an error. In this particular case, we specify that the square function takes a single int parameter and returns an int value.
This says nothing about the square function itself or how it operates - that's provided by the definition of the square function later on.
A function definition also serves as a declaration; if both the caller and called function are in the same translation unit (source file), then you can put the definition before the call and not have to mess with a separate declaration at all:
/** main.c */
#include <stdio.h>
int square( int num )
{
return num * num;
}
int main( int argc, char **argv )
{
int a = 4;
int a_squared = square( a );
printf( "Square of %d is %d\n", a, a_squared );
return 0;
}
This is actually preferable as you don't have to update the function signature in two different places. It means your code reads "backwards", but honestly it's a better way to do it.
However, if you separate your function out into a separate source file, then you need to have a separate declaration:
/** main.c */
#include <stdio.h>
int square( int num );
int main( int argc, char **argv )
{
int a = 4;
int a_squared = square( a );
printf( "Square of %d is %d\n", a, a_squared );
return 0;
}
/** square.c */
int square( int num )
{
return num * num;
}
When it's processing main.c, the compiler doesn't know anything about the definition of the square function in square.c - it doesn't even know the file exists. It doesn't matter if main.c is compiled before square.c or vice-versa; the compiler operates on one file at a time. The only thing the compiler knows about the square function is that declaration in main.c.
Having to manually add a declaration for every function defined in the separate .c file is a pain, though - you wouldn't want to write a separate declaration for printf, scanf, fopen, etc. So BY CONVENTION we create a separate .h file with the same name as the .c file to store the declarations:
/** main.c */
#include <stdio.h>
#include "square.h"
int main( int argc, char **argv )
{
int a = 4;
int a_squared = square( a );
printf( "Square of %d is %d\n", a, a_squared );
return 0;
}
/** square.h */
int square( int num );
/** square.c */
int square( int num )
{
return num * num;
}
By convention, we also add include guards to the .h file - this keeps the contents of the file from being processed more than once per translation unit, which can happen if you #include "square.h" and include another header which also includes square.h.
/** square.h */
#ifndef SQUARE_H // the contents of this file will only be
#define SQUARE_H // processed if this symbol hasn't been defined
int square( int num );
#endif
Also by convention, we include the .h file in the .c file to make sure our declarations line up with our definitions - if they don't, the compiler will complain:
/** square.c */
#include "square.h"
int square( int num )
{
return num*num;
}
After both main.c and square.c have been compiled, their object code will be linked into a single executable:
main.c ------+-----> compiler ---> main.o ----+--> linker ---> main
| |
square.h ----+ |
| |
square.c ----+-----> compiler ---> square.o --+
We must compile both C files and link their object code together to have a working program. No doubt your IDE makes this easy - you just add source files to the project and it builds them correctly. gcc lets you do it all in one command, but you must list all the .c files in the project.
If you're running from the command line, you can use the make utility to simplify things. You'll need to create a Makefile that looks something like this:
CC=gcc
CFLAGS=-std=c11 -pedantic -Wall -Werror
main: main.o square.o
all: main
clean:
rm -rf main *.o
All you need to do then is type make at the command line and it will build your project, using built-in rules for compiling main.c and square.c.

Functions from header file not working without including .c too

I try to make program in C and I cant use functions from .h without including .c file too. If I include .c after including .h it works. I get "undefined reference to ..." error on every function defined in .h.
main.c:
#include "mp.h"
//#include "mp.c"
int main()
{
int n;
printf("Unesite broj clanova niza: ");
scanf("%d",&n);
int *a=(int *)malloc(n*sizeof(int));
if (a==NULL) exit(0);
unos(a,n);
sortiranje(a,n,rastuci);
stampanje(a,n);
sortiranje(a,n,opadajuci);
stampanje(a,n);
return 0;
}
mp.h:
#ifndef MP_H_INCLUDED
#define MP_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
enum tip_sort {opadajuci,rastuci};
void unos(int *, int);
void sortiranje(int *, int, enum tip_sort);
void stampanje(int *, int);
#endif // MP_H_INCLUDED
mp.c:
#include "mp.h"
void unos(int *a, int n){
...
}
void sortiranje(int *a, int n, enum tip_sort t){
...
}
void stampanje(int *a, int n){
...
}
What you're seeing is a linker error. I guess, you're trying to compile main.c all alone.
You compilation statement should look like
gcc main.c mp.c -o output
and yes, do not #include .c (source) files. Source files are meant to be compiled and linked together to form the binary.
Note: Also, please do not cast the return value of malloc().

Multiple Definition of a function in C, Prototyping

Eclipse tells me that I have mutliple Definitions of a function.
I just can't spot the mistake.
This is my main.c
#include <stdio.h>
#include "kontaktverzeichnis.h"
int main(){
kontakt_hinzufuegen();
return 0;
}
This is the header:
#ifndef KONTAKTVERZEICHNIS_H_
#define KONTAKTVERZEICHNIS_H_
#include "kontaktfunktionen.c"
int kontakt_hinzufuegen();
#endif /* KONTAKTVERZEICHNIS_H_ */
and this is kontaktfunktionen.c
#include <stdio.h>
kontakt[];
kontakt_hinzufuegen(){
int i = 0;
printf("Bisher sind %i Kontakte angelegt.",kontakt[i]);
kontakt[i++];
}
struct kontaktname{
char* name;
char* vorname;
};
struct kontaktanschrift{
char* strasse;
int hausnummer;
int plz;
char* ort;
char* land;
};
Where is my error?
You're not supposed to #include C files, that's not the proper way to organize your code.
You should compile the C files separately and then link them together, or compile them all at once with a single compiler invocation.
Do not #include anything in your header file. And do a #include "kontaktverzeichnis.h" in the kontaktfunktionen.c file.
As #StoryTeller commented, define your kontakt_hinzufuegen() as int kontakt_hinzufuegen() in the kontaktfunktionen.c file and return an int value from the function kontakt_hinzufuegen as for ex::
#include <stdio.h>
#include "kontaktverzeichnis.h"
// define the type for this array as below
int kontakt[];
int kontakt_hinzufuegen(){
int i = 0;
printf("Bisher sind %i Kontakte angelegt.",kontakt[i]);
kontakt[i++];
// Return an int value
return 0 ;
}
Your error is that in kontaktfunktionen.h you are including kontaktfunktionen.c. This will include all the definitions and declarations from kontaktfunktionen.c which are already declared when you use kontaktfunktionen.c
As others have said: You should not include .c files in your header files.

C program compiles but no output

I am trying to learn creating header file in C and including it in my main.c func() . I created a simple tut1.c file with function named call() and a tut1.h header file which externs tut1.c function named call(). Thats it, now i am using eclipse Juno for C/C++ on linux fedora. I dont get any compile error but the code wont output? I tried on console and eclipse in vain. Can you check please? Thanks
---main.c-----
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "tut1.h"
int main (void)
{
int tut1(void);
return 0;
}
-----tut1.c------
#include <stdio.h>
#include <stdlib.h>
#include "tut1.h"
int call (void)
{
int *ptr;
int i;
ptr = &i;
*ptr = 10;
printf ("%d we are printing the value of &i\n", &i);
printf ("%d we are printing the value of *ptr\n", *ptr);
printf ("%d we are printing the value of ptr\n", ptr);
printf ("%d we are printing the value of &ptr\n", &ptr);
getchar();
return 0;
}
----tut1.h----
#ifndef TUT1_H_
#define TUT1_H_
extern int call (void);
#endif
You're not seeing anything because you're not calling the call() function from your main() function.
The main() function is the default entry point when you run the program, i.e. the first function that gets called during execution.
To execute the function call() you would need to call this from main() as follows :
int main (void)
{
int result = call();
return 0;
}
BTW, this line int tut1(void); within your main() just declares a function, which you do not seem to have defined anywhere. So I have removed it in the above shown code.

Resources