passing an array of structs from a function to the main program - c

I have a data file of about 2500 lines. Each line contains 5 parameters. I declare a strut out side of a routine.
typedef struct data
{
char date[9];
char time[3];
float price;
float NAV;
float percent_change;
} _data ;
void readfile(int *j, struct data *input);
void readfile(int *j,struct data *input)
I set aside memory to read each line of the file into an array of structs.
input = calloc(days_of_data,sizeof(*input));
for (i = 0; i< days_of_data; i++)
input[i] = *(_data*)calloc(1,sizeof(_data));
and read the file.
while(fgets(line, 75, fp) != NULL)
{
date = strtok(line,",");
strcpy(input[i].date,date);
time = strtok(NULL,",");
strcpy(input[i].time, time);
price = strtok(NULL,",");
input[i].price = atof(price);
NAV = strtok(NULL,",");
input[i].NAV = atof(NAV);
percent_change = strtok(NULL,",");
input[i].percent_change = atof(percent_change);
i--;
}
This works. Now I want to sent the structure to the main program.
int main(int argc, const char * argv[]) {
struct data *input;
readfile(&j, input);
printf("%f\n",input[0].percent_change);
}
This compiles but crashes on the print statement.

You will have to use return value
struct data * readfile(int *j) {
struct data *input;
/* read the data */
return input;
}
int main(int argc, const char * argv[]) {
struct data *input;
input = readfile(&j);
printf("%f\n",input[0].percent_change);
}
or pointer
void readfile(int *j, struct data **input_out) {
struct data *input;
/* read the data */
*input_out = input;
}
int main(int argc, const char * argv[]) {
struct data *input;
readfile(&j, &input);
printf("%f\n",input[0].percent_change);
}
to pass the data to the caller.

Related

Pass String array and indexes using Struct to a thread in C

I am trying to pass a string array and indexes from where to start end searching in the array, I am unable to solve it from the last two days. I am sending to the pthread_create a struct data thread_data, here i am able to send the int and long data, but not the string array, can someone help me, how to pass these.
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
char * str;
};
struct data thread_data[NUM_THREADS];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
char * str[3];
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
.....
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
...
char work[]={"First Line","Second line","Third line"};
...
while(fgets(arr[index],120, fp)!=NULL){
index=index+1;
thread_data[index].tid=index;
thread_data[index].str=work;
...
rc=pthread_create(&threads[index],NULL,searchString,(void *)&thread_data[index]);
...
}
pthread_exit(NULL);
}
To hold the multiple strings you need 2D array.
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
You need to use pointer to pointer in struct data to hold the above array.
struct data{
.....
const char **str;
size_t lenOfStr;
};
And pass the length of array explicitly to thread function from main function.
Your sample code may look like below.
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
const char **str;
size_t lenOfStr;
};
struct data thread_data[3];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
const char **str = NULL;
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
int i = 0;
for (i = 0;i<t_data->lenOfStr;i++)
printf("%s\n", str[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
int index = 0;
pthread_t threadid=0;
thread_data[index].tid=index;
thread_data[index].str=work;
thread_data[index].lenOfStr = sizeof(work)/sizeof(*work); // Calculate the size of work here
int rc=pthread_create(&threadid,NULL,searchString,&thread_data[index]);
pthread_exit(NULL);
}

C code - segmentation fault

I'm trying to compile my c code, but I always get Segmentation fault after I execute my program. Here is part of my code:
LINE_LENGTH=300
struct clip {
int views;
char *user;
char *id;
char *title;
char *duration;
struct clip *next;
} *head;
my main function, where argv[1] is my csv file
int main(int argc, char **argv) {
int n;
head = build_a_lst(*(argv+1));
return 0;}
The rest of my code
struct clip *build_a_lst(char *fn) {
FILE *fp;
struct clip *hp;
char *fields[5];
char line[LINE_LENGTH];
int cnt=0,i;
hp=NULL;
fp=fopen(fn,"r");
if(fp=NULL)
exit(EXIT_FAILURE);
while(fgets(line,LINE_LENGTH,fp)!=NULL){
split_line(fields,line);//fields has five values stored
hp=append(hp,fields);
for(i=0;i<5;i++){
free(fields[i]);
fields[i]=NULL;
}
}
return hp;
}
void split_line(char **fields,char *line) {
int i=0;
char *token, *delim;
delim = ",\n";
token=strtok(line,delim);//ok line
for(;token!=NULL;i++){
fields[i]=malloc(strlen(token)+1);
strcpy(fields[i],token);
token=strtok(NULL,delim);
}
}
struct clip *append(struct clip *hp,char **five) {
struct clip *cp,*tp;
tp=malloc(sizeof(struct clip));
tp->views=atoi(five[1]);
tp->user=malloc(strlen(five[0]+1));
tp->duration=malloc(strlen(five[2]+1));
tp->id=malloc(strlen(five[3]+1));
tp->title=malloc(strlen(five[4]+1));
strcpy(tp->user,five[0]);
strcpy(tp->duration,five[2]);
strcpy(tp->id,five[3]);
strcpy(tp->title,five[4]);
cp=hp;
while(cp!=NULL)
cp=cp->next;
cp->next=tp;
hp=cp;
return hp;
}
According to some articles segmentation fault is caused by trying to read or write an illegal memory location. And since I am allocating memory in different parts of my code, the problem should be there. Can someone please help me with this. Thank you in advance.
There are some problems with your code:
if(fp=NULL) should be if(fp == NULL)
char *fields[5]; should be char *fields[5] = {NULL};
for(;token!=NULL;i++){ should be for(; token != NULL && i < 5; i++){
These:
tp->user=malloc(strlen(five[0]+1));
tp->duration=malloc(strlen(five[2]+1));
tp->id=malloc(strlen(five[3]+1));
tp->title=malloc(strlen(five[4]+1));
should be
tp -> user = malloc(strlen(five[0]) + 1);
tp -> duration = malloc(strlen(five[2]) + 1);
tp -> id = malloc(strlen(five[3]) + 1);
tp -> title = malloc(strlen(five[4]) + 1);
You don't free several of the malloced memory.

Array of struct from binary file

I have to write a function that will read an array of structures of type Product with data from a binary file.This file contains the number of products - nr and a number of articles of type Product. What's wrong? Thank you in advance!
#define SIZE 30
typedef struc{
int id;
char[SIZE] name;
float price;
}Product;
void create(Product *p, FILE *fptr)
{
p = malloc(sizeof(Product));
fread(p, 1, sizeof(Product), fptr);
}
int main(int argc, char* argv[])
{
FILE *fptr = fopen(argv[1],"rb");
Product *p;
create(p, fptr);
return 0;
}
You have to modify it to something like this:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 30
typedef struct{
int id;
char name[SIZE];
float price;
}Product;
int readproducts(Product *p, FILE *fptr, int nr)
{
if(nr != fread(p, sizeof(Product), nr, fptr))
return -1;
return 0;
}
int main(int argc, char* argv[])
{
FILE *fptr = fopen(argv[1],"rb");
int nr = 0;
if(NULL == fptr) return -1;
// First read number of products from file
// Assuming this number is written as 4 byte integer - at the start of file
if(fread(&nr, 4, 1, fptr) != 1)
return -1;
// Now, read the products
Product *p = malloc(nr * sizeof(Product));
if(-1 == readproducts(p, fptr, nr))
return -1;
fclose(fptr);
return 0;
}
The way you had used malloc in your function was wrong, see here why.
PS. That said, binary writing/reading might not be portable across different computers.

Error in create and reserve memory for struct array

I have to create a function for read settings with this struct and format parameters (I can't change).
text file:
key1:value1
key2:value2
....
format:
typedef struct {
char *key;
char *value;
}configParam;
void loadSettings(char fileName[],configParam *paramsReaded[], int *length, int *statusCode);
and my code:
void loadSettings(char fileName[],configParam *paramsReaded[], int *length, int *statusCode){
*paramsReaded = (configParam*)malloc((*length)*sizeof(configParam));
int j;
for(j=0; j<*length; j++){
*paramsReaded[j].key = (char *)malloc(MAX_STRING*sizeof(char));
*paramsReaded[j].value = (char *)malloc(MAX_STRING*sizeof(char));
}
FILE *file = fopen(fileName,"rb");
char line[100];
char *token;
int i,k;
if (file == NULL){
printf("\nError de lectura: archivo no encontrado\n");
*statusCode = 0;
exit(1);
}
while (feof(file) == 0){
fgets(line,100,file);
token = strtok(line,":");
strcpy(*paramsReaded[i].key, token);
token = strtok(NULL,":");
strcpy(*paramsReaded[i].value, token);
i++;
}
fclose(file);
for(k=0; k<*length; k++){
printf ("\nclave[%d]: %s \nvalor[%d]: %s\n",k , *paramsReaded[k].key,k , *paramsReaded[k].value);
}
}
int main(){
char route[] = "settings_entrada.txt";
int lengthSettings;
int statusCode = 1; // set in 0, if finds a error
countLines(route,&lengthSettings); //only count lines of txt
configParam parametersReaded[];
loadSettings (route, &parametersReaded,&lengthSettings,&statusCode);
}
code::blocks shows me
request for member 'key' in something not a structure or union
request for member 'value' in something not a structure or union
I'm not sure if either declare the struct array parametersReaded :(

Struct arrays in C

Hi I'm having trouble trying to initializing each element of the struct array. When I try and assign the value ZERO to both 'bSize' and 'msgs', it doesn't work as it errors out when i get to malloc. In the printf statement it prints a -1852803823 number. Excuse the messy code as i'm playing around trying to figure it out.
struct message{
int *data;
int bSize;
int msgs;
};
int main(int argc, char *argv[]) {
.....
}
void getSchedFile (FILE *file, int **schd) {
struct message sMsg[nodeCount];
const int pakSize = 6;
// Iniitialise message buffer
for (int i=0; i<nodeCount; i++){
sMsg[i].bSize = 0;
sMsg[i].msgs = 0;
printf("bSize %d\n",sMsg[i].bSize);
}
/* Get the number of bytes */
fseek(file, 0L, SEEK_SET);
int time;
while((fscanf(file, "%d", &time)) != EOF){
int src;
fscanf(file, "%d", &src); // get source node id
// These are here for easier reading code
int aPos = sMsg[src].bSize;
int nMsg = sMsg[src].msgs;
printf("size %d\n", sMsg[src].bSize);
if (sMsg[src].bSize==0){
sMsg[src].data = malloc( pakSize * sizeof(int));
}else{
sMsg[src].data = realloc(sMsg[src].data, (aPos+pakSize)*sizeof(int));
}
Where is the nodeCount value coming from? Is it a global variable? You should be very careful with global variables, and avoid using them if possible.
Pass the nodeCount in the method parameter and as Charlie mentioned, check it for > 0

Resources