I can't get this function for creating strings from file - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#define MAX_SIZE 100
#define ODIT "log_file.txt"
#define INVENTORY_N "inventory_names.txt"
#define INVENTORY_A "inventory_amount.txt"
#define CURR_DIR "main-2dynamic"
static int inventory_amount_array[MAX_SIZE];
static char inventory_names_array[MAX_SIZE][MAX_SIZE];
void print_avail_opt(){
printf("1) Read from the log file\n");
printf("2) Save the current inventory in the log file\n");
printf("3) Print current inventory item amounts\n");
printf("4) Print current inventory item names\n");
printf("5) Exit\n");
}
void get_inventory_int(){
int i,n;
char *token;
char help[256];
FILE *InputFile;
InputFile = fopen(INVENTORY_A, "r");
fscanf(InputFile, "%s", help);
token = strtok(help, ",");
i = 0;
while(token != NULL){
inventory_amount_array[i] = atoi(token);
token = strtok(NULL, ",");
i++;
}
n = i;
}
void get_inventory_string(){
int i,n;
char *token;
char help[256];
FILE *InputFile;
InputFile = fopen(INVENTORY_A, "r");
fscanf(InputFile, "%s", help);
token = strtok(help, ",");
i = 0;
while(token != NULL){
inventory_names_array[i][i] = token;
token = strtok(NULL, ",");
i++;
}
n = i;
}
void print_inventory_int(){
int n = 10;
get_inventory_int();
for (int i = 0; i<n; i++){
if( inventory_amount_array[i] == '\0'){
break;
}
else{
printf("Available stock from item:%d\n",inventory_amount_array[i]);
}
}
}
void print_inventory_string(){
int n = 10;
get_inventory_string();
for (int i = 0; i<n; i++){
if(inventory_names_array[i][i] == '\0'){
break;
}
else{
printf("Available stock from %s\n",inventory_names_array[i]);
}
}
}
void f_print_inventory_int(FILE * log_file){
int n;
get_inventory_int();
for (int i = 0; i<n; i++){
if( inventory_amount_array[i] == '\0'){
break;
}
else{
fprintf(log_file,"%d ",inventory_amount_array[i]);
}
}
}
int read_from_file(FILE * log_file){
log_file = fopen(ODIT, "r");
char str[MAX_SIZE];
while(fscanf(log_file,"%s", str)!=EOF){
printf("%s", str);
}
fclose(log_file);
}
int write_in_file(FILE * log_file, int tm_year, int tm_mon, int tm_mday,int tm_hour, int tm_min, int tm_sec){
log_file = fopen(ODIT, "a");
fprintf(log_file,"\nInventory at %02d.%02d.%02d - %02d:%02d:%02d\n", tm_mday, tm_mon, tm_year, tm_hour, tm_min,tm_sec);
f_print_inventory_int(log_file);
fclose(log_file);
}
int restock (){
}
int main(){
time_t T = time(NULL);
struct tm tm = *localtime(&T);
FILE * log_file;
bool loop = true;
while (loop == true){
print_avail_opt();
printf("Enter op:");
int op = 0;scanf("%d", &op);
switch (op){
case 1: read_from_file(log_file);
break;
case 2: write_in_file(log_file, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
break;
case 3: print_inventory_int();
break;
case 4: print_inventory_string();
break;
case 5: loop = false;
break;
default: printf("Not correct option\n");
break;
}
}
return 0;
}
I want to make case 4 in the main switch to work properly
The things that are not working are the way of creating strings arrays and printing it out - everything else works fine.
PS: And i would really appreciate a working functions, because i have it for homework at school and it's due tomorrow.
Note from my compiler (gcc):
main.c: In function ‘get_inventory_string’:
main.c:57:37: warning: assignment to ‘char’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]
57 | inventory_names_array[i][i] = token;
|

Just as the compiler warning said, your error is here:
inventory_names_array[i][i] = token;
inventory_names_array[i][i] is a char; token is a pointer. You need to dereference the pointer (note: this will clear this error, but you have other problems in your code, too).

The compiler is warning you that you are assigning a char* pointer to a single char value in this statement:
inventory_names_array[i][i] = token;
That is not what you want or need. You need to copy the characters pointed at by token into the array. You can use strncpy() for that:
strncpy(inventory_names_array[i], token, MAX_SIZE);
That being said, there are other problems with your code:
not checking fopen() for failure.
not closing opened files with fclose().
not preventing buffer overflows.
your get functions are not storing n anywhere that your print function can reach, so you end up looping through the arrays using incorrect counts. You should have the get functions return the actual array counts to the caller.
read_from_file() and write_in_file() both take in a FILE* parameter that they don't use. Also, they are declared as returning an int, but they don't actually return anything.
With that said, try something more like this instead:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#define MAX_SIZE 100
#define ODIT "log_file.txt"
#define INVENTORY_N "inventory_names.txt"
#define INVENTORY_A "inventory_amount.txt"
#define CURR_DIR "main-2dynamic"
static int inventory_amount_array[MAX_SIZE];
static char inventory_names_array[MAX_SIZE][MAX_SIZE];
void print_avail_opt(){
printf("1) Read from the log file\n");
printf("2) Save the current inventory in the log file\n");
printf("3) Print current inventory item amounts\n");
printf("4) Print current inventory item names\n");
printf("5) Exit\n")
}
int get_inventory_int(){
int i = 0;
char help[256];
FILE *InputFile = fopen(INVENTORY_A, "r");
if (InputFile == NULL) return 0;
fscanf(InputFile, "%255s", help);
fclose(InputFile);
char *token = strtok(help, ",");
while (token != NULL && i < MAX_SIZE){
inventory_amount_array[i] = atoi(token);
token = strtok(NULL, ",");
++i;
}
return i;
}
int get_inventory_string(){
int i = 0;
char help[256];
FILE *InputFile = fopen(INVENTORY_A, "r");
if (InputFile == NULL) return 0;
fscanf(InputFile, "%255s", help);
fclose(InputFile);
char *token = strtok(help, ",");
while (token != NULL && i < MAX_SIZE){
strncpy(inventory_names_array[i], token, MAX_SIZE);
token = strtok(NULL, ",");
++i;
}
return i;
}
void print_inventory_int(){
int n = get_inventory_int();
for (int i = 0; i < n; ++i){
if (inventory_amount_array[i] == 0){
break;
}
printf("Available stock from item: %d\n", inventory_amount_array[i]);
}
}
void print_inventory_string(){
int n = get_inventory_string();
for (int i = 0; i < n; ++i){
if (inventory_names_array[i][i] == '\0'){
break;
}
printf("Available stock from %s\n", inventory_names_array[i]);
}
}
void f_print_inventory_int(FILE * log_file){
int n = get_inventory_int();
for (int i = 0; i < n; ++i){
if (inventory_amount_array[i] != 0){
fprintf(log_file, "%d ", inventory_amount_array[i]);
}
}
}
void read_from_file(){
FILE *log_file = fopen(ODIT, "r");
if (log_file == NULL) return;
char str[MAX_SIZE];
while (fscanf(log_file, "%99s", str) == 1){
printf("%s", str);
}
fclose(log_file);
}
void write_in_file(int tm_year, int tm_mon, int tm_mday, int tm_hour, int tm_min, int tm_sec){
FILE *log_file = fopen(ODIT, "a");
if (log_file == NULL) return;
fprintf(log_file, "\nInventory at %02d.%02d.%02d - %02d:%02d:%02d\n", tm_mday, tm_mon, tm_year, tm_hour, tm_min,tm_sec);
f_print_inventory_int(log_file);
fclose(log_file);
}
int main(){
time_t T = time(NULL);
struct tm tm = *localtime(&T);
bool loop = true;
while (loop){
print_avail_opt();
printf("Enter op:");
int op = 0; scanf("%d", &op);
switch (op){
case 1:
read_from_file();
break;
case 2:
write_in_file(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
break;
case 3:
print_inventory_int();
break;
case 4:
print_inventory_string();
break;
case 5:
loop = false;
break;
default:
printf("Not correct option\n");
break;
}
}
return 0;
}

Related

Problems working on CSV archive and array of structures on C

I am a complete beginner. I am trying to use strtok in C to read a
CSV file, and store the contents into an array structure for each column, but I have a "segmentation fault" message. I will appreciate any advice. Before this I should make a column for deaths/cases and sorting the lines in ascending order, but first I should fix this code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 200
#define COUNT 2
typedef struct data_s {
char iso[SIZE];
char continent[SIZE];
char location[SIZE];
char date[SIZE];
unsigned int cases;
unsigned int deaths;
} data_t;'
int j = 1;
int main()
{
FILE *myfile;
myfile = fopen("owid-covid-data-small.csv", "r");
if (myfile == NULL)
{
printf("Archivo no encontrado.");
}
rewind(myfile);
char myLine[SIZE];
char *delimiter = ",";
char buffer[SIZE];
memset(buffer, 0, sizeof(buffer));
int i = 0;
for (char c = getc(myfile); c != EOF; c = getc(myfile))
{
if (c == '\n')
{
j++;
}
}
data_t temp_data[j];
memset(&temp_data, 0, j*sizeof(data_t));
rewind(myfile);
while (fgets(myLine, 200, (FILE*)myfile) != NULL && i<j)
{
strcpy(temp_data[i].iso, strtok(myLine, delimiter));
strcpy(temp_data[i].continent, strtok(myLine, delimiter));
strcpy(temp_data[i].location, strtok(myLine, delimiter));
strcpy(temp_data[i].date, strtok(myLine, delimiter));
temp_data[i].cases = atoi(strtok(NULL, delimiter));
strncpy(buffer, strtok(NULL, delimiter), SIZE);
temp_data[i].deaths = atoi(buffer);
memset(buffer, 0, sizeof(buffer));
i++;
for (int i = 0; i < COUNT; i++)
{
printf("Country: %s\n", temp_data[i].location);
printf("Continent: %s\n", temp_data[i].continent);
printf("Date: %s\n", temp_data[i].date);
printf("Total cases: %u\n", temp_data[i].cases);
printf("Total deaths: %u\n", temp_data[i].deaths);
printf("\n");
}
memset(&temp_data, 0, sizeof(data_t));
}
fclose(myfile);
}

Trying to write numbers from a .txt to a binary file

I am currently reading a text file that is below:
New York,4:20,3:03
Kansas City,12:03,3:00
North Bay,16:00,0:20
Kapuskasing,10:00,4:02
Thunder Bay,0:32,0:31
I have the city names being fprintf to a new .txt file which works fine, however I am trying to take the times and print them to a binary file and am stuck as to where I am having an issue. Any help would be appreciated.I need to store the times as 04, 20 for "New York" in a 2 byte value and having issues parsing to have this specifically.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable: 4996)
// a function to remove the trailing carraige return
void clearTrailingCarraigeReturn(char* buffer);
/* == FUNCTION PROTOTYPES == */
/* == CONSTANTS == */
// MAIN
typedef struct
{
char cityName[20];
short flightTime;
short layoverTime;
} Flight;
Flight parseFlight(char* line) {
char delimiter[2] = ",";
Flight flight;
char* token = strtok(line, delimiter);
int i = 0;
while (token != NULL)
{
if (i == 0)
{
strcpy(flight.cityName, token);
}
if (i == 1)
{
flight.flightTime = atoi(token);
}
if (i == 2)
{
flight.layoverTime = atoi(token);
}
token = strtok(NULL, delimiter);
i++;
}
return flight;
}
int main(int argc, char* argv[])
{
FILE *fpIn, *fpOut, *fbOut;
char line[80];
Flight flight;
fpIn = fopen(argv[1], "r");
fpOut = fopen("theCities.txt", "w+");
fbOut = fopen("theTimes.dat", "wb+");
while (fgets(line, 1024, fpIn) > 0)
{
clearTrailingCarraigeReturn(line);
printf(" >>> read record [%s]\n", line);
flight = parseFlight(line);
fprintf(fpOut, "%s\n", flight.cityName);
fwrite(&flight.flightTime, sizeof(short), 1, fbOut);
fwrite(&flight.layoverTime, sizeof(short), 1, fbOut);
}
fclose(fpIn);
fclose(fpOut);
fclose(fbOut);
}
// This function locates any carraige return that exists in a record
// and removes it ...
void clearTrailingCarraigeReturn(char* buffer)
{
char* whereCR = strchr(buffer, '\n');
if (whereCR != NULL)
{
*whereCR = '\0';
}
}
Perhaps something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Time_s
{
unsigned char hours;
unsigned char minutes;
} Time_t;
typedef struct Flight_s
{
char cityName[20];
Time_t flightTime;
Time_t layoverTime;
} Flight_t;
// a function to remove the trailing carraige return
void clearTrailingCarraigeReturn(char *buffer)
{
int more;
do {
size_t index;
index = strlen(buffer);
if(!index)
break;
--index;
switch(buffer[index])
{
case '\n':
case '\r':
buffer[index] = '\0';
more = 1;
break;
default:
more = 0;
break;
}
} while(more);
return;
}
int ParseTime(char *timeStr, Time_t *time)
{
int rCode=0;
char *next;
time->hours = (unsigned char)strtoul(timeStr, &next, 10);
if(':' == *next)
{
++next;
time->minutes = (unsigned char)strtoul(next, NULL, 10);
}
return(rCode);
}
Flight_t parseFlight(char* line)
{
char delimiter[2] = ",";
Flight_t flight;
char *token = strtok(line, delimiter);
int i = 0;
while(token)
{
switch(i)
{
case 0:
strcpy(flight.cityName, token);
break;
case 1:
ParseTime(token, &flight.flightTime);
break;
case 2:
ParseTime(token, &flight.layoverTime);
break;
}
token = strtok(NULL, delimiter);
i++;
}
return(flight);
}
int main(int argc, char* argv[])
{
int rCode=0;
FILE *fpIn=NULL, *fpOut=NULL, *fbOut=NULL;
char line[80+1];
Flight_t flight;
if(argc < 2)
{
fprintf(stderr, "ERROR: argc < 2\n");
goto CLEANUP;
}
fpIn = fopen(argv[1], "r");
if(!fpIn)
{
fprintf(stderr, "ERROR: fopen(\"%s\",\"r\")\n", argv[1]);
goto CLEANUP;
}
fpOut = fopen("theCities.txt", "w+");
if(!fpOut)
{
fprintf(stderr, "ERROR: fopen(\"theCities.txt\",\"w+\")\n");
goto CLEANUP;
}
fbOut = fopen("theTimes.dat", "wb+");
if(!fbOut)
{
fprintf(stderr, "ERROR: fopen(\"theTimes.dat\",\"wb+\")\n");
goto CLEANUP;
}
while(fgets(line, sizeof(line), fpIn) > 0)
{
clearTrailingCarraigeReturn(line);
flight = parseFlight(line);
printf("%s,%02hhu:%02hhu,%02hhu:%02hhu\n",
flight.cityName,
flight.flightTime.hours, flight.flightTime.minutes,
flight.layoverTime.hours, flight.layoverTime.minutes
);
fprintf(fpOut, "%s\n", flight.cityName);
fwrite(&flight.flightTime, sizeof(Time_t), 1, fbOut);
fwrite(&flight.layoverTime, sizeof(Time_t), 1, fbOut);
}
CLEANUP:
if(fpIn)
fclose(fpIn);
if(fpOut)
fclose(fpOut);
if(fbOut)
fclose(fbOut);
return(rCode);
}

Replace a word in C

can you advice me? I have a string from a file. When i see the string on my console, i need to write the word on which i want to change, and output the result in another file. For example: "Hello my girl" the word i want change "girl" on another word "boy". I can use the library
Can you advice me the algorithm which helps me to change the word?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char my_string[256];
char* ptr;
FILE *f;
if ((f = fopen("test.txt", "r"))==NULL) {
printf("Cannot open test file.\n");
exit(1);}
FILE *out;
if((out=fopen("result.txt","w"))==NULL){
printf("ERROR\n");
exit(1);
}
fgets (my_string,256,f);
printf ("result: %s\n",my_string);
ptr = strtok (my_string," ");
while (ptr != NULL)
{
printf ("%s \n",ptr);
ptr = strtok (NULL," ");
}
char old_word [10];
char new_word [10];
char* ptr_old;
char* ptr_new;
printf ("Enter your old word:\n");
ptr_old= gets (old_word);
printf ("Your old word:%s\n",old_word);
printf ("Enter new old word:\n");
ptr_new = gets (new_word);
printf ("Your new word:%s\n",new_word);
fclose(f);
fclose(out);
return 0;
}
i tried to split inputting string into words. Now its dead end.
This code will help you. you have to pass 4 args at runtime.
./a.out "oldword" "newword" "file name from take the old word" "file name where to copy"
$ ./a.out girl boy test.txt result.txt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int args, char *argv[4])
{
FILE *f1;
FILE *f2;
char *strings=0;
char *newstrings=0;
char *token=NULL;
strings=(char *)malloc(1000);
newstrings=(char *)malloc(1000);
if((strings==NULL)||(newstrings==NULL))
{
printf("Memory allocation was not successfull.");
return 0;
}
if(args<4)
{
puts("Error: Not enough input parameters");
puts("Usage: ./change <oldword> <newword> <infile> <newfile>");
return 0;
}
f1=fopen(argv[3],"r");
f2=fopen(argv[4],"w");
if(f1==NULL)
{
puts("No such file exists");
return 0;
}
while(fgets(strings,1000,f1)!=NULL)
{
if(strstr(strings,argv[1])!=NULL)
{
token=strtok(strings,"\n\t ");
while(token!=NULL)
{
if(strcmp(token,argv[1])==0)
{
strcat(newstrings,argv[2]);
strcat(newstrings," ");
}
else
{
strcat(newstrings,token);
strcat(newstrings," ");
}
token=strtok(NULL,"\n\t ");
}
}
else
{
strcpy(newstrings,strings);
}
fputs(newstrings,f2);
}
free(strings);
free(newstrings);
printf("New file <%s> generated!\n",argv[4]);
fclose(f1);
fclose(f2);
return 0;
}
You can use a function like the shown function in the demonstrative program below
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char * replace(const char *s, const char *src, const char *dsn)
{
size_t n = 0;
size_t src_len = strlen(src);
size_t dsn_len = strlen(dsn);
for (const char *p = s; (p = strstr(p, src)) != NULL; p += src_len)
{
n++;
}
char *result = malloc(strlen(s) + n * (src_len - dsn_len) + 1);
const char *p = s;
char *t = result;
if (n != 0)
{
for (const char *q; (q = strstr(p, src)) != NULL; p = q + src_len)
{
memcpy(t, p, q - p);
t += q - p;
memcpy(t, dsn, dsn_len);
t += dsn_len;
}
}
strcpy(t, p);
return result;
}
int main( void )
{
char s[] = " the girl and boy are relatives";
char *p = replace(s, "girl", "boy");
puts(s);
puts(p);
free(p);
}
The program output is
the girl and boy are relatives
the boy and boy are relatives
#include <stdio.h>
#include <string.h>
int main ()
{
char file_path[40] = { 0 }, stf[255] = { 0 }, rtf[255] = { 0 }, str[255] = { 0 };
FILE* file = NULL;
FILE *e_f;
if((e_f=fopen("result.txt","w"))==NULL){
printf("ERROR\n");
exit(1);
}
do
{
printf("Enter file path: ");
fgets(file_path, 40, stdin);
file_path[strlen(file_path) - 1] = '\0';
file = fopen(file_path, "r+");
}
while(file == NULL);
printf("Enter text to find: ");
fgets(stf, 255, stdin);
stf[strlen(stf) - 1] = '\0';
printf("Enter text to replace: ");
fgets(rtf, 255, stdin);
rtf[strlen(rtf) - 1] = '\0';
while(fgets(str, 255, file) != NULL)
{
char* tmp_ptr = strstr(str, stf);
while(tmp_ptr != NULL)
{
char tmp_str[255];
strcpy(tmp_str, tmp_ptr + strlen(stf));
strcpy(str + strlen(str) - strlen(tmp_ptr), rtf);
strcat(str, tmp_str);
tmp_ptr = strstr(str, stf);
}
printf("%s", str);
}
fclose(file);
fclose(e_f);
return 0;
}
That was i need. Thanks everybody for helping!
I did a function:
#include <stdio.h>
#include <string.h>
#define MAX 50
void Change (char x[], char cx, char nu){
int i;
for(i=0;i<strlen(x);i++) {
if (x[i]==cx){
x[i] = nu;
}
}
}
int main () {
char str[MAX];
char ch;
char new;
printf("Insert the string\n");
scanf("%s",str);
printf("Insert the word that you want to change\n");
scanf(" %c",&ch);
printf("the new word\n");
scanf(" %c",&new);
Change(str, ch, new);
printf("The new word is %s\n",str );
return 0;
}

while using fgets and printf in C, it appears "00“ in the screen, do you know why and where "00" comes from?

I want print every line of one file, and I also want divide each line into several parts in a array and then use atoi() to change the string into int, but eventually I get a wired 00 in the end, I don't know where it comes from, can anybody help?
#include <stdio.h>
#include <stdlib.h>
#include "tabu.h"
#include <stdbool.h>
#include <string.h>
int main(int argc, const char *argv[]) {
int city[30][30];
FILE *fp = fopen("/Users/wuchangli/Desktop/Cpractice/tabu_6010/tabu_6010_/tabu_6010_/30.in", "r");
if (fp == NULL) {
printf("error");
}
char data[20];
int n = 0;
char *token;
int ct[3];
int mm = 0;
while (fgets(data, 30, fp) != NULL) {
//fflush(stdin);
//fflush(stdout);
//fflush(stdin);
//fflush(stdout);
//printf("\n%s\n", data);
printf("\n%s\n", data);
token = strtok(data, " ");
while (token != NULL && n > 0) {
printf("%s\n", token);
ct[mm] = atoi(token);
printf("%d\n", ct[mm]);
token = strtok(NULL, " ");
mm++;
}
city[ct[0]][ct[1]] = ct[2];
printf("%d", city[ct[0]][ct[1]]);
city[ct[1]][ct[0]] = ct[2];
printf("%d", city[ct[1]][ct[0]]);
n++;
}
//for (int ii = 0; ii < 30; ii++) {
// for (int jj = 0; jj < 30; jj++) {
// printf("%d%d is %d\n", ii, jj, city[ii][jj]);
// }
//}
fclose(fp);
return 0;
}
here is the link of my files:enter link description here
You have two issues :-
in this part you are continuously increasing the mm++ but not initialize the mm again when you are going to read another line from file. issue is array bound error.
while(fgets(data, 30, fp)!=NULL){
printf("data is = %s\n", data);
edited: mm=0;
token=strtok(data, " ");
while(token!=NULL)
{
printf("token is = %s\n", token);
ct[mm]=atoi(token);
printf("%d....%d\n",mm,ct[mm]);
token=strtok(NULL, " ");
mm++;
}
Second issue is :-
you have one arrey city[30][30], where row and column, both are 30.
in you code you reading a file that conation string like "30 435", and performed strtok() operation on each string and saved conversion of string to int in ct[0] = 30 and ct[1] = 435. you got issue because array bound checking.
ct[1] is 435 but you define city[30[30].
city[ct[0]][ct[1]]=ct[2];
printf("%d", city[ct[0]][ct[1]]);
city[ct[1]][ct[0]]=ct[2];
printf("%d", city[ct[1]][ct[0]]);

C - Opening differents files using same pointer

I'm trying to retrieve informations by many plain-text files, which will be then stored in a proper struct. To do so, I'm using a function that takes member of the struct to populate and source of the plain-text file where the informations are stored.
Posting my "test" code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _elem
{
const char *title;
int ok;
int almost;
int nope;
int hits;
float last_rank;
};
typedef struct _elem Chapter;
Chapter *generate_array(const char *source, int *elems);
int engine_start(Chapter *elem, char *source);
int main()
{
const char path_f[100];
int elements = 0;
int i = 0;
Chapter *dict;
printf("Insert the name of the source:\n");
scanf("%s", path_f);
printf("\nGenerating dictionary, please wait...\n");
dict = generate_array(path_f, &elements);
if (dict == NULL)
{
printf("Aborting.\n");
exit(1);
}
while (i < elements)
{
printf("Element %d:\n", (i + 1));
printf("\nTitle: %s\n", dict[i].title);
printf("Ok: %10d\n", dict[i].ok);
printf("Almost: %5d\n", dict[i].almost);
printf("Nope: %8d\n", dict[i].nope);
printf("Hits: %8d\n", dict[i].hits);
printf("Rank: %8.2f\n", dict[i].last_rank);
printf("\n");
i++;
}
return EXIT_SUCCESS;
}
Chapter *generate_array(const char *source, int *elems)
{
FILE *src;
int sources;
int i = 0;
char **srcs;
Chapter *generated;
src = fopen(source, "r");
if (src == NULL)
{
printf("[!!] Error while reading file!\n");
return NULL;
}
fscanf(src, "%d", &sources);
if (sources <= 0)
{
printf("[!!] Wrong number of sources, exiting.\n");
return NULL;
}
srcs = (char **) malloc(sizeof(char *) * sources);
while (i < sources && !feof(src))
{
srcs[i] = (char *) malloc(sizeof(char) * 100);
fscanf(src, "%s", srcs[i++]);
}
fclose(src);
generated = (Chapter *) malloc(sizeof(Chapter) * i);
*elems = i;
i = 0;
while (i < *elems)
{
if(engine_start( &generated[i], srcs[i] )) i++;
else
{
printf("[!!] Error in file %s, aborting.\n", srcs[i]);
return NULL;
}
}
return generated;
}
int engine_start(Chapter *elem, char *source)
{
FILE *parser;
int done = 0;
parser = fopen(source, "r");
if (parser == NULL) printf("[!!] Error while opening %s, aborting.\n", source);
else
{
fgets(elem->title, 100, parser);
fscanf(parser, "%d %d %d %d %f", &(elem->ok), &(elem->almost),
&(elem->nope), &(elem->hits),
&(elem->last_rank) );
fclose(parser);
done = 1;
}
return done;
}
Now this is the main file where are stored paths to the other plain-text files:
lol.dat
5
lold/lol1.dat
lold/lol2.dat
lold/lol3.dat
lold/lol4.dat
lold/lol5.dat
And one example of lolX.dat:
Qual'è la vittoria di cristo?
3 4 5 12 44.9
I'm getting SIGSEGV after the first iteration of "engine_start", probably due to FILE *parser (but I can be totally wrong, I don't know at this point).
Someone can guide me through this problem? Thank you.
Make the following changes and try-
struct _elem
{
char *title; // allocate the memory for this.
int ok;
int almost;
int nope;
int hits;
float last_rank;
};
You need to allocate memory for element title before assigning something to it.
int engine_start(Chapter *elem, char *source)
{
FILE *parser;
int done = 0;
parser = fopen(source, "r");
if (parser == NULL) printf("[!!] Error while opening %s, aborting.\n", source);
else
{
elem->title=(char *)malloc(100); // include this line.
fgets(elem->title, 100, parser);
fscanf(parser, "%d %d %d %d %f", &(elem->ok), &(elem->almost),
&(elem->nope), &(elem->hits),
&(elem->last_rank) );
fclose(parser);
done = 1;
}
return done;
}

Resources