Error in create and reserve memory for struct array - c

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 :(

Related

A function that return values from a structure in C

I have this struct in C language.
struct webit{
char indice[10];
int prid;
double latitude;
char date[20];
double longitude;
int xspeed;
int rEvt;
int alti;
int seq1;
int seq2;
int presi;
char cod1[5];
char cod2[5];
int iint1;
int iint2;
int x15;
};
and I have this function already putted before the struct webit
tramafunction();
this is how the function works: receive a string of delimited by commas and then split the data to a 15 diferent variables, this is an example of a string :
/*¶bL0 L3,01,+08590323,-079343001,010215,00000000000000,-tN,000,012689997,001219456,000,7FF2,C07F,0,4,*/
Function:
trama function(){
struct webit wbt;
char buf[103]="";
scanf("%[^\t\n]s",buf);
printf("\n \n Trama Recibida=[%s]\n\n", buf);
int z;
z=strlen(buf);
printf("TAMANO DE LA TRAMA: %d",z);
int i = 0;
char *p = strtok (buf, ",");
char *array[16]={0};
while (p != NULL)
{
array[i++] = p;
p = strtok (NULL, ",");
}
for (i = 0; i <16; ++i){
wbt.x15 = 0;
if (array[15] != NULL){
wbt.x15=atoi(array[15]);
}
printf("DATA: [%s]\n", array[i]);
}
strcpy(wbt.indice,array[0]);
printf("INDEX: [%s]\n",wbt.indice); /*AND EVENTUALLY WITH ALL OTHER DIFERENT DATA TYPES VARIABLES*/
}
in the main
int main()
{
tramafunction();
return 0;
}
At the end they convert the 15 data types of the array into the variables of webit in this case defined wbt. example "wbt.indice"
HOW CAN MAKE THE FUNCTION TRAMA RETURN ALL THE VALUES OF wbt. so I can use it anywhere in the programas, another function, another struct. etc

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

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.

Hash Table - Sort Structure with qsort

Alright sorry for creating another question but the last one got overwhelmed and chaotic.
So I'm making a hash table which inserts words from a file (tokens) and after I have inserted them I need to sort them. The program template was given, the only functions that weren't complete were : insert_ht() , clear_ht() and compare. Even though I've done tons of search about qsort with compare, the program doesn't sort the frequencies (number of times each word was inserted) . I want em sorted from the highest to lowest.
Here is the code : "note that i shouldn't change any function except insert_ht() , clear_ht() and compare
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
struct node *new_list;
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
new_list = malloc(sizeof(link));
new_list->token = strdup(token) ;
new_list->freq = 1;
new_list->next = htable[hashval];
htable[hashval] = new_list;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
void clear_ht()
{
int i;
for(i=0; i<HTABLE_SIZ; i++) {
while(htable[i]->token!=NULL) {
htable[i]->token=NULL;
htable[i]->freq=NULL;
free(htable[i]);
}
}
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if (p1->freq > p2->freq)
return(+1);
else if (p1->freq < p2->freq)
return(-1);
else
return(0);
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}

Why does this part gives segmentation fault?

This is an incomplete code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define W 1031
#define B 256
struct FileCoordinates{
int x; /*line number*/
int y; /*word number*/
struct FileCoordinates *next;
};
struct FileStruct{
char *filename;
struct FileCoordinates *coordinates;
struct FileStruct *next;
};
struct WordStruct{
char *word;
struct WordStruct *left;
struct WordStruct *right;
struct FileStruct *files;
};
typedef struct FileCoordinates *CoorPtr;
typedef struct FileStruct *FilePtr;
typedef struct WordStruct *WordPtr;
WordPtr HashTable[W];
long int power(int a, long b){
long int pow, i;
pow = 1;
for (i = 0; i < b; i++){
pow = pow*a;
}
return pow;
}
int hashvalue (char *word){
long int i, value=0, n;
n = strlen(word);
for (i=0; i<n; i++){
value = value + power(B,n-i-1) * word[i];
}
return(value%W);
}
void putPosition(int x, int y, FilePtr *currfile){
CoorPtr currcors = (*currfile)->coordinates;
while (currcors!=NULL){
currcors = currcors->next;
}
currcors = (CoorPtr)malloc(sizeof(struct FileCoordinates));
currcors->x=x;
currcors->y=y;
}
void putFile(char *filename, WordPtr *currWord, int x, int y){
FilePtr currfile = (*currWord)->files;
while(currfile != NULL && strcmp(currfile->filename,filename)!=0){
currfile=currfile->next;
}
if (strcmp(currfile->filename,filename)==0){
putPosition(x, y, &currfile);
}
else{
currfile = (FilePtr)malloc(sizeof(struct FileStruct));
currfile->filename = filename;
putPosition(x, y, &currfile);
}
}
void insert(char *word, WordPtr *leaf, char *filename, int x, int y)
{
if( *leaf == NULL )
{
*leaf = (WordPtr) malloc( sizeof( struct WordStruct ) );
(*leaf)->word = word;
putFile(filename, &(*leaf), x, y);
/* initialize the children to null */
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(word < (*leaf)->word)
{
insert( word, &(*leaf)->left, filename, x, y);
}
else if(word > (*leaf)->word)
{
insert( word, &(*leaf)->right, filename, x, y);
}
else if(word == (*leaf)->word){
putFile(filename, &(*leaf), x, y);
}
}
int main(int argc, char *argv[]){
int i, words, lines, value;
char *filename, *word, c;
FILE *fp;
word = (char *)malloc(21*sizeof(char));
if (argc<2){
perror("no files were inserted");
}
for (i=1; i<argc; i++){
words=1;
lines=1;
fp = fopen(argv[i], "r");
if (fp==NULL){
printf("Could not open file named %s! \n", argv[i]);
return 2;
}
filename = malloc( strlen( argv[i] ) + 1 );
strcpy( filename, argv[i] );
fscanf(fp, "%s", word);
value=hashvalue(word);
c=getc(fp);
insert(word, &HashTable[value], filename, lines, words);
if (c==' '){
words = words+1;
}
else if(c=='\n'){
lines=lines+1;
words=1;
}
}
system("PAUSE");
return 0;
}
And debugger gives me segmentation fault at this part:
while(currfile != NULL && strcmp(currfile->filename,filename)!=0){
currfile=currfile->next;
}
The reason of the code is to get text files as arguments, sort the words into binary trees placed in the hashtable and then by searching the keyword it shows you the coordinates it appears.
Anyway, i know this is a very novice code but im trying to understand.
You forget to set currfile->next to NULL when you create the object:
currfile = (FilePtr)malloc(sizeof(struct FileStruct));
currfile->filename = filename;
Reserve space with calloc instead of malloc, or add:
currfile->next = NULL;
Where do you initialize files? (Hint: you don't). This means it is an undefined value (not necessarily NULL). You need to initialize files before calling putFile.
As noted in the comment, once you fix that one, you need to do the same for next in both FileCoordinates and FileStruct and for coordinates in FileStruct.
Also as noted in the comments, you reuse the word buffer, meaning that all the nodes in the tree will have the same string. You should allocate a new buffer for the string when it is stored in the tree. Perhaps use strdup.
(*leaf)->word = strdup(word);
Once that is fixed, you also need to work on your string comparison. if(word == (*leaf)->word) compares the pointers, not their contents. You need to use strcmp if you want to compare the actual string data.
else if(strcmp(word, (*leaf)->word) == 0){

Structure issue using C

I'm trying to store strings into dynamical allocated memory. I'm able to break the strings down and store them within the members of the struct and print them perfectly within the function readFile, but when it comes to printing it in main, it's only printing the last scan and everything else is null. I'm thinking that maybe I'm not allocating the array of structures correctly. Here's my program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef _MSC_VER
#include <crtdbg.h> // needed to check for memory leaks (Windows only!)
#endif
#define MEM_ERROR printf("Not enough memory\n")
#define FLUSH while( getchar() != '\n' )
typedef struct
{
char id[5];
char *name;
int *sales;
int total;
int low;
int high;
}PERSON;
typedef struct
{
int worker;
int weeks;
PERSON *pAry;
}HEADER;
// Function Declaration
void valiFile(char nameIn[]);
FILE* openFile(char nameIn[]);
void getHeader(FILE* fpFile, HEADER *pHead);
PERSON* aloPerson(int workers);
void readFile(FILE* fpFile, HEADER *pHead);
char* aloName(HEADER *pHead, int strCount);
void repeat(char nameIn[]);
int main ( void )
{
// Local Declaration
FILE* fpFile;
char nameIn[25];
char *endPro = "end";
HEADER *pHead = (HEADER*)calloc(1, sizeof(HEADER));
// Statement
printf("Please select file to to open.\nsales or sales_2: ");
scanf("%s", nameIn);
FLUSH;
do
{
valiFile(nameIn);
fpFile = openFile(nameIn);
getHeader(fpFile, pHead);
readFile(fpFile, pHead);
//printf("%s\n", pHead->pAry[0].id);
//free(pHead);
repeat(nameIn);
}
return 0;
}// main
/* ========== valiFile ==========
========== */
void valiFile(char nameIn[])
{
// Local Declaration
char *file = "sales";
char *file2 = "sales_2";
int i;
int check = 0;
// Statement
do
{
for(i = 0; nameIn[i]; i++)
{
nameIn[i] = tolower(nameIn[i]);
}
if(strcmp(file, nameIn) != 0)
{
if(strcmp(file2, nameIn) != 0)
{
printf("\nPlease enter a valid file.\n");
printf("sales or sales_2: ");
scanf("%s", nameIn);
FLUSH;
}
else
check = 1;
}
else
check = 1;
}
while(check != 1)
;
return;
}// valiFile
/* ========== openFile ==========
========== */
FILE* openFile(char nameIn[])
{
// Local Declaration
FILE* fpFile;
char *strSale = "sales";
// Statement
if(strcmp(strSale, nameIn) == 0)
{
fpFile = fopen("sales.txt", "r");
if(fpFile == NULL)
{
printf("File didn't read correcty.\n");
exit(100);
}
}
else
{
fpFile = fopen("sales_2.txt", "r");
if(fpFile == NULL)
{
printf("File didn't read correcty.\n");
exit(100);
}
}
return fpFile;
}// openFile
/* ========================= getHeader ========================
============================================================*/
void getHeader(FILE* fpFile, HEADER *pHead)
{
// Local Declaration
int worker, salesWeek, i;
PERSON *list;
// Statement
fscanf(fpFile, "%d %d", &worker, &salesWeek);
list = aloPerson(worker);
HEADER header = {worker, salesWeek, list};
*pHead = header;
return;
}// getHeader
/* aloPerson
*/
PERSON* aloPerson(int worker)
{
// Local Declaration
PERSON *list;
// Statement
list =(PERSON*)calloc(worker, sizeof(PERSON));
if(list == NULL)
{
MEM_ERROR, exit(103);
}
return list;
}// aloPerson
/* readFile
*/
void readFile(FILE* fpFile, HEADER *pHead)
{
// Local Declaration
char temp[50];
int strCount = 0;
char *loc;
char *ptr;
int i;
// Statement
fscanf(fpFile, "%*d %*d");
for(i = 0; i < pHead->worker; i++)
{
while(fgets(temp, sizeof(temp), fpFile))
{
ptr = temp;
loc = strchr(temp, ' ');
strncpy(pHead->pAry[i].id, temp, (loc - ptr));
ptr += (loc - temp);
*ptr++;
loc = strchr(temp, ';');
strCount = (loc - ptr);
pHead->pAry[i].name = aloName(pHead, strCount);
strncpy(pHead->pAry[i].name, ptr, (loc - ptr));
ptr += (loc - ptr);
printf("%s\n", pHead->pAry[i].name);
}
}
return;
}// readFile
/* aloName
*/
char* aloName(HEADER *pHead, int strCount)
{
// Local Declaration
char *names;
// Statement;
names = malloc((strCount + 1)*sizeof(char));
return names;
}

Resources