Passing arguments to another .c file - c

I've looked around for a good while if someone else has posted the same question and I haven't seen found an answer that applies to me.
Heres my problem:
When I pass 3 arguments (located in main) to another .c file, the information erases. If I keep the function inside main (not passing the arguments to another .c file) the program works just fine.
What am I missing here?
Also, I'm using a microcontroller, but I'm sure the problem is in my code.
main:
#include <avr/io.h>
#include <stdbool.h>
#include <stdio.h>
#include "glcd.h"
#include "fonts/Liberation_Sans15x21_Numbers.h"
//functions used:
void glcd_print_clock(void);
void time_clock(void);
void display_clock_text(uint8_t x, uint8_t y, uint8_t z);
int main(void)
{
glcd_init();
while(1)
{
time_clock();
}
}
//
void time_clock(void)
{
uint8_t sec, min, hr;
//char str_time[8] = "";
for(hr=1; hr<13; hr++)
{
for(min=0; min<60; min++)
{
for(sec=0; sec<60; sec++)
{
display_clock_text(hr,min,sec);
/*
//clears buffer
glcd_clear_buffer();
glcd_set_font(Liberation_Sans15x21_Numbers,15,21,46,57);
//sends hr, min, and sec to string
sprintf(str_time,"%02d:%02d:%02d",hr,min,sec);
//x-y coordinate of text
glcd_draw_string_xy(12,5,str_time);
//displays text
glcd_write();
_delay_ms(1000);
*/
}
}
}
}
Other .c file (display_text):
#include "glcd.h"
#include "fonts/Liberation_Sans15x21_Numbers.h"
#include <stdio.h>
#define Y_AXIS 5
#define X_AXIS 12
void display_clock_text(uint8_t x, uint8_t y, uint8_t z);
/* Gets the hour, minutes and seconds from main.
Then displays the information on the LCD
*/
void display_clock_text(uint8_t x, uint8_t y, uint8_t z)
{
char str_time[8] = "";
//clears buffer
glcd_clear_buffer();
//selects font to be used
glcd_set_font(Liberation_Sans15x21_Numbers,15,21,46,57);
//sends hr, min, and sec to string
sprintf(str_time,"%02d:%02d:%02d", x, y, z);
//x-y coordinate of text
glcd_draw_string_xy(X_AXIS,Y_AXIS,str_time);
//displays text
glcd_write();
_delay_ms(1000);
}

The line char str_time[8] = ""; is incorrect. It should be char str_time[9] = "";. This is because sprintf(str_time,"%02d:%02d:%02d", x, y, z); requires 9 bytes because of the terminating 0.
Also, a good idea, in general, would be:
snprintf(str_time, sizeof(str_time), "%02d:%02d:%02d", x, y, z);
This may or may not be causing the undesirable behavior that you are experiencing but it for sure needs to be fixed.

Related

print result using system calls

For my OS class, I need to print out the result of this matrix multiplication using only system calls. Following my lecture notes, I wrote up this piece of code. I use :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 1000
// Matrix
long long int A[N][N],B[N][N],R[N][N];
int main(int argc, char *argv[])
{
int x,y,z;
char str[100];
/* Matrix inicialization */
for(y=0;y<N;y++)
for(x=0;x<N;x++)
{
A[y][x]=x;
B[y][x]=y;
R[y][x]=0;
}
/* Matrix multiplication */
for(y=0;y<N;y++)
for(z=0;z<N;z++)
for(x=0;x<N;x++)
{
R[y][x]+= A[y][z] * B[z][x];
}
//System calls for printing the result
sprintf(str,"%lld\n",R);
write(1,str,strlen(str));
exit(0);
}
Now, it's printing a just a 14295680 in the console. The professor gave us a file with machine code and it's printing 332833500, which seems more reasoneable.
Thanks in advance.
Edit: changed type on the printf call
Edit2: fix R[N][N]
Just replace the sprintf value:
sprintf(str,"%lld\n",R[N-1][N-1]); // = 332833500
write(1,str,strlen(str));
instead of
sprintf(str,"%lld\n",R); // this is a pointer
write(1,str,strlen(str));

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;
}

Generating packets in C

I am not receiving anything in buffer. Wherever I printf my buffer, it is always empty or shows garbage value. Can anyone help?
I defined header, packet and called them in my main, but buffer still shows garbage.
#include <stdint.h>
struct header {
uint16_t f1;
uint16_t f2;
uint32_t f3;
};
struct data {
uint16_t pf1;
uint64_t pf2;
};
#include <arpa/inet.h>
#include <string.h>
#include <stdint.h>
#include "packet.h"
void htonHeader(struct header h, char buffer[8]) {
uint16_t u16;
uint32_t u32;
u16 = htons(h.f1);
memcpy(buffer+0, &u16, 2);
printf("Value of buff is: %hu\n",buffer);
u16 = htons(h.f2);
memcpy(buffer+2, &u16, 2);
u32 = htonl(h.f3);
memcpy(buffer+4, &u32, 4);
}
void htonData(struct data d, char buffer[10]) {
uint16_t u16;
uint32_t u32;
u16 = htons(d.pf1);
memcpy(buffer+0, &u16, 2);
u32 = htonl(d.pf2>>32);
memcpy(buffer+2, &u32, 4);
u32 = htonl(d.pf2);
memcpy(buffer+6,&u32, 4);
}
void HeaderData(struct header h, struct data d, char buffer[18]) {
htonHeader(h, buffer+0);
htonData(d, buffer+8);
printf("buff is: %s\n",buffer);
}
#include <stdio.h>
#include "packet.c"
#include <string.h>
#include<stdlib.h>
int main(){
struct header h;
struct data d;
char buff[18];
//printf("Packet is: %s\n",buff);
printf("Generating Packets..... \n");
h.f1=1;
d.pf1=2;
h.f2=3;
d.pf2=4;
h.f3=5;
HeaderData(h,d,buff);
strcat(buff,buff+8);
printf("Packet is: %s\n",buff);
return 0;
}
The problem is that your printf()s are either syntactically wrong (printf( "%hu", ... ); expects an unsigned short as parameter, but you pass a pointer) or you try to print buff by using "%s" but the content is binary, not text. What you could do instead was doing some kind of hexdump, like:
int i;
for( i=0; i<sizeof( buff ); i++ ) {
printf( "%x ", buff[i] & 0xff );
}
puts( "" ); // terminate the line
Please note, that using sizeof works im main() only, in the other function you've got to determine the buffer size differently.
Besides: because of the binary content of buff, you can't use strcat(). Even if you have made sure that there is a '\0' behind the last value you have copied (I haven't checked if you have), depending on the integer values you copy, there may be another '\0' value before that one and strcat() would overwrite everything form that point on.

initializing global variables from a text file in C

I have a beginner question in C. I'm having trouble in reading a file with values that initialize global variables to be shared in different C files. My true project has many variables to be used and changed across multiple files. My file that reads the parameters is:
#include <stdio.h>
#include <stdlib.h>
#include "parameters.h"
#include "prototypes.h"
#define MAX_LENGTH 100
int ReadParameters(void)
{
char line[MAX_LENGTH];
FILE *fp = fopen("parameters.in", "r");
if (! fp)
return EXIT_FAILURE;
int numread = 0;
while (fgets(line, MAX_LENGTH, fp)) {
numread += sscanf(line, "x = %d", &x);
numread += sscanf(line, "y = %d", &y);
numread += sscanf(line, "z = %d", &z);
}
fclose(fp);
return numread;
}
I defined the variables x, y, and z as external in a header file:
#ifndef PARAMETERS_H
#define PARAMETERS_H
extern int x;
extern int y;
extern int z;
#endif
The prototype of ReadParameters.c is in the header prototype.h and the values in x, y, and z are used in main.c:
#include <stdio.h>
#include <stdlib.h>
#include "parameters.h"
#include "prototypes.h"
int main()
{
ReadParameters();
printf("The value of x: %d\n", x);
printf("The value of y: %d\n", y);
printf("The value of z: %d\n", z);
x += 15;
y -= 5;
z -= 20;
printf("Now the value of x: %d\n", x);
printf("Now the value of y: %d\n", y);
printf("Now the value of z: %d\n", z);
return EXIT_SUCCESS;
}
When I compile I get the error of undefined reference to x, y, and z which I believe its because I only declared the variables not defined them. If I remove extern from the header file I get no errors and it runs but I read its not good practice to define variables in header files. If I make a another .C file and defined the variables there:
#include "parameters.h"
int x, y, z;
it works but is this ok to do? I'm new to programming and any suggestions would be appreciated. Thanks
extern means that the variables are available in some other compilation unit (ie. .c file). Typically you have one .h file for each .c file that "exposes" anything to other units.
So for something like this, I would probably have:
parameters.c
int x, y, z;
parameters.h
#ifndef PARAMETERS_H
#define PARAMETERS_H
extern int x;
extern int y;
extern int z;
#endif
main.c
#include "parameters.h"
int foo() {
x = 4; // setting x from parameters.c
}
extern tells the compiler that the definition of the variables lies else where( special case would be where variables are defined in the same compilation unit ). But linker should find these definitions. So, declare them extern in a header file(s) and include the header file in source files intended to use them. But don't forget to define them in exactly one source file. What you are doing seems ok to me.
it works but is this ok to do?
It is indeed regarded as bad practice, since it leads to "tight coupling" and spaghetti code.
The preferred way is this:
//parameters.h
void set_x (int x);
//parameters.c
#include "parameters.h"
static int private_x; // static means: only visible/accessible from parameters.c
void set_x (int x)
{
private_x = x;
}
// main.c
#include "parameters.h"
set_x (something);

C pointers - allocate a global pointer in one file using it in another file?

I need several global pointers to be shared among a few files - the pointers are essentially arrays of double whose lengths are only determined at runtime.
I include here the pieces of the code that caused the issue. This is not the exact code, but it illustrates all the points precisely:
foo.h
#ifndef FOOH
#define FOOH
/* ------------------
COMMON VARIABLES
---------------------*/
// create_bundles.c
extern double *all_bundle;
/* ------------------
COMMON FUNCTIONS
---------------------*/
// create_bundles.c
void create_bundles(int num_firm);
// memory_allocation.c
void allocate_memory(int num_firm, int num_bundle);
void clean_memory(void);
#endif
create_bundles.c
#include "foo.h"
extern double *all_bundle;
void create_bundles(int num_firm) {
int i;
for (i = 0; i < num_firm; i++) {
all_bundle[i] = 1
}
memory_allocation.c
#include "foo.h"
// create_bundles.c
double *all_bundle = NULL;
void allocate_memory(int num_firm, int num_bundle) {
all_bundle = calloc(num_bundle * num_firm, sizeof(double));
}
void clean_memory(void) {
free(all_bundle);
}
main.c
#include "foo.h"
void main(int num_firm, int num_bundle) {
allocate_memory(num_firm, num_bundle);
create_bundles(num_firm);
clean_memory();
}
What happened is that if I print out all_bundle[i] it'll all be 0, and then it'll give me a segmentation error.
Why the error and how to fix it?
The problem is not in global pointer, but something else. Keep looking for the problem in your common code. I hope you are trying to print contents of all_bundle array before calling clean_memory. I have edited your code a little bit and it works great without any segmentation errors and prints 1.0000. Here it is, take a look:
foo.h:
#ifndef FOOH
#define FOOH
// create_bundles.c
extern double *all_bundle;
// create_bundles.c
void create_bundles(int num_firm);
// memory_allocation.c
void allocate_memory(int num_firm, int num_bundle);
void clean_memory(void);
#endif
memory_allocation.c:
#include <stdlib.h>
#include "foo.h"
double *all_bundle = 0;
void allocate_memory(int num_firm, int num_bundle) {
all_bundle = calloc(num_bundle * num_firm, sizeof(double));
}
void clean_memory(void) {
free(all_bundle);
}
create_bundles.c:
#include "foo.h"
void create_bundles(int num_firm) {
int i;
for (i = 0; i < num_firm; i++) {
all_bundle[i] = 1;
}
}
main.c:
#include <stdio.h>
#include "foo.h"
int main(int argc, char *argv[]) {
allocate_memory(100, 1);
create_bundles(100);
{
int i;
for(i = 0; i < 100; ++i)
printf("%f\n", all_bundle[i]);
}
clean_memory();
return 0;
}
Have a header file to access the memory (i.e. add stuff to it, remove stuff from it, readf bits of it, etc).
Have the corresponding .c (or .cpp if that fancies you) to do the magic. And then use static to define the memory.
This is a simple and easy solution to your problem and also enables you to change the implementation if it is required to do so.

Resources