Recovering colums/rows Matrix from a file - c

so i've this program that scan and print the matrix from a file. anyways the program i have works with normal matrix i mean Square matrix but now i want to make a manual matrix i mean i've to enter the number of lines/columns and then i call the lines and columns in the main.
So the program below explains the situation
int recuperation (int t[][20], char *nomFichier){
int nbElement=0 ,i,j,nbElement2=0;
FILE *fp;
fp=fopen(nomFichier,"r");
if(fp!=NULL)
{
fscanf(fp,"%d\n",&nbElement);
fscanf(fp,"%d\n",&nbElement2);
if(nbElement && nbElement2)
{
for(i=1;i<=nbElement;i++)
{
for(j=1;j<=nbElement2;j++)
{
fscanf(fp,"%d",&t[i-1][j-1]);
}
}
}
}
else
printf("\n Fichier vide \n");
return nbElement;
}
You see the return? nbElement that's the number of lines but i want to return the number of columns too, which is nbElement2.
Because later in main() i've to call this function by typing:
l= recuperation(t,txtfile)
but i can't call the columns since i returned only 1 value.
Hope that you got what i mean, thanks.

The best thing to do is to provide the columns and rows as pointers to the function. This way, when you assign values to those variables, they change outside of the function too.
int recuperation (int t[][20], char *nomFichier, int * rows, int * columns){
int i,j;
FILE *fp;
fp=fopen(nomFichier,"r");
if(fp!=NULL)
{
fscanf(fp,"%d\n",rows);
fscanf(fp,"%d\n",columns); // already a pointer
if(*rows && *columns) // dereference the pointer to get the value
{
for(i=1;i<=*rows;i++)
{
for(j=1;j<=*columns;j++)
{
fscanf(fp,"%d",&t[i-1][j-1]);
}
}
}
}
else
printf("\n Fichier vide \n");
return 0;
}

Related

String in structure gets deleted

I'm working on the last exercise of the "Think like a computer scientist, C version" book and I have some trouble with one particular point.
The exercise consists of making a small game, where the computer picks a random value between 0 and 20 and then asks me to guess the number.
After that, the computer counts the number of tries I made and, if I get a better score than the previous party, I need to store my name and the number of tries in a structure.
My problem is the following: When I restart the game, the string value, player_name, in the structure gets somehow deleted but player_score is still there.
First, I made a "call by value" function to create the structure and then a tried with a "call by reference" but getting the same results.
I think I tried everything I could with my actual knowledge for now; so, if someone could check my code and give me some tips about what's wrong I would much appreciate it!
//HEADERS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define FALSE 0
#define TRUE 1
//TYPEDEF STRUCTS
typedef struct
{
int player_score;
char *player_name;
} HS_Player;
//FUNCTION PROTOTYPES
int Random_Value(void);
int Get_User_Choice(void);
int Check_Result(int computer, int my_choice);
int Try_Again(int game_result, int computer);
void Player_Infos(HS_Player *player_p, int score);
int Game_Restart(void);
//MAIN
int main(void)
{
int end_game;
int high_score_value = 100;
HS_Player player;
while (end_game != TRUE)
{
int computer_number = Random_Value();
printf("Guess the number between 0 et 20 chosen by the computer.\n");
int your_number = Get_User_Choice();
int result_game = Check_Result(computer_number, your_number);
int tries_to_win = Try_Again(result_game, computer_number);
printf("Number of tries: %i\n", tries_to_win);
if (tries_to_win < high_score_value)
{
Player_Infos(&player, tries_to_win );
high_score_value = player.player_score;
}
printf("Highest score: %i By: %s\n", player.player_score, player.player_name);
printf("\n");
end_game = Game_Restart();
}
return EXIT_SUCCESS;
}
//Random_Value FUNCTION
int Random_Value(void)
{
srand(time(NULL));
int x = rand();
int y = x % 20;
return y;
}
//Get_User_Choice FUNCTION
int Get_User_Choice(void)
{
int success, x;
char ch;
printf("Your Guess:\t");
success = scanf("%i", &x);
while (success != 1)
{
printf("Your input is not a number. Please try again:\t");
while ((ch = getchar()) != '\n' && ch != EOF);
success = scanf("%i", &x);
}
if (x < 0 || x > 20)
{
printf("Your input must be between 0 and 20. Please try again.\n");
Get_User_Choice();
}
return x;
}
//Check_Result FUNCTION
int Check_Result(int computer, int my_choice)
{
int check_result;
if (my_choice < computer)
{
printf("Computer number is larger!\n");
check_result = FALSE;
}
else if (my_choice > computer)
{
printf("Computer number is smaller!\n");
check_result = FALSE;
}
else if (my_choice == computer)
{
printf("It's a Match! You chose the same number than the computer.\n");
printf("\n");
check_result = TRUE;
}
return check_result;
}
//Try_Again FUNCTION
int Try_Again(int game_result, int computer)
{
int tries_befor_success = 1;
while (game_result != TRUE)
{
int your_number = Get_User_Choice();
game_result = Check_Result(computer, your_number);
tries_befor_success++;
}
return tries_befor_success;
}
//Player_Infos FUNCTION
void Player_Infos(HS_Player *player_p, int score)
{
char new_name[80];
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
scanf("%s", new_name);
printf("\n");
player_p->player_score = score;
player_p->player_name = new_name;
}
//Game_Restart FUNCTION
int Game_Restart(void)
{
int quit_value;
printf("Quit Game ?\n");
printf("Press 'y' to quit or any other keys to continue.\n");
fflush(stdin);
char quit_game = getchar();
printf("\n");
if (quit_game == 'y')
{
quit_value = TRUE;
}
else
{
quit_value = FALSE;
}
return quit_value;
}
The problem is that, in your Player_Infos function, you are assigning the address of a local array to the char* player_name pointer member of the passed structure. When that function ends, the local array it used will be deleted and the pointer in the structure will be invalid. (In the case of the player_score, you don't have that problem, because the given value is copied to the structure member.)
There are several ways around this; one would be to use the strdup() function to make a copy of the local char new_name[80]; array – but that is really overkill, and you would need to manage (i.e. free()) that allocated string whenever you make a modification.
A simpler way is to make the player_name member an actual array of char and then use strcpy() to copy the local array into that member.
Better, still, with the player_name member defined as char [80], you can read directly into that (in the function), and avoid the local array completely:
typedef struct
{
int player_score;
char player_name[80];
} HS_Player;
//...
void Player_Infos(HS_Player *player_p, int score)
{
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
// Read directly. Limit input to 79 chars (allowing room for null terminator).
scanf("%79s", player_p->player_name);
printf("\n");
player_p->player_score = score;
}
Also, just as a "style" tip, you may want to change the member names to just score and name, as the "player" part is implied by the structure type-name itself.
This issue you are having is that you are associating the player name pointer to a variable that goes out of scope when you leave the "player_Infos" function. What you probably would want to do is define the name as a character array in your structure and then use the "strcpy" call in your function instead. Following is a couple of code snippets illustrating that point.
//TYPEDEF STRUCTS
typedef struct
{
int player_score;
char player_name[80];
} HS_Player;
Then, in your function, use the "strcpy" call.
//Player_Infos FUNCTION
void Player_Infos(HS_Player *player_p, int score)
{
char new_name[80];
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
scanf("%s", new_name);
printf("\n");
player_p->player_score = score;
strcpy(player_p->player_name, new_name);
//player_p->player_name = new_name;
}
When I tested that out, I got a name to appear in the terminal output.
Computer number is smaller!
Your Guess: 4
It's a Match! You chose the same number than the computer.
Number of tries: 8
Highest score: 4 By: Craig
FYI, you will need to include the "string.h" file.
Give that a try.
Name Update
The reason your player.player_name is not getting updated is because you can't assign a string this way in C. When doing player_p->player_name = new_name; you're actually saving in player_p->player_name the memory address of new_name.
Instead, what you want to achieve, is to copy each character of new_name to player_p->player_name and in order to achieve this, you have to change the type of prlayer_name field from char* player_name to char player_name[80], then assign it using, for example, strcpy():
#include <string.h>
// [...]
//TYPEDEF STRUCTS
typedef struct
{
unsigned int player_score;
char player_name[80];
} HS_Player;
// [...]
//Player_Infos FUNCTION
void Player_Infos(HS_Player *player_p, int score)
{
char new_name[80];
printf("Congrats! Your made a new high score.\n");
printf("What's your name ?\t");
scanf("%s", new_name);
printf("\n");
player_p->player_score = score;
strcpy(player_p->player_name, new_name);
}
Data Persistence
To make data (players info) persistent over multiple runs, you have to save the content of the struct to a file.
Example
int Save_Score(char* filename, HS_Player* player)
{
FILE* file = fopen(filename, "w");
if (file == NULL)
{
fprintf(stderr, "\nAn error occurred while opening the file\n");
return -1;
}
if (fprintf(file, "%d %s", player->player_score, player->player_name) < 0)
return -1;
fclose(file);
return 0;
}
int Load_Score(char* filename, HS_Player* player)
{
FILE* file = fopen(filename, "r");
if (file == NULL)
{
fprintf(stderr, "\nAn error occurred while opening the file\n");
return -1;
}
if (fscanf(file, "%d %79s", &player->player_score, player->player_name) < 0)
return -1;
fclose(file);
return 0;
}

how to change the program to do the same task without the program crashing?

I have an assignment to produce a program that will compare students answer to the answer key, and display the incorrect answers. The program then produces a report of the students incorrect answers and his final grade. The Program must use arrays and functions.
Currently I am trying to code two functions one to read the students answer file and store it in an array and the other to read answer key file and store it in another array. Then the functions will return both arrays to the main function later to be sent to another function to compare their contents(not yet done).
My problem with this code after pressing F11 to compile and run, i get a blank execution screen and a notification saying that the program has stopped working.
If my code contains a mistake or my approach is incorrect please tell me how to fix it.
note: this is my first semester learning C programming.
Thank you.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
//Modules
char* readstudent()
{
FILE*s_ans;
int i,j;
static char arrs[20];
s_ans=fopen("trial2.txt","r");
if (s_ans == NULL)//check if file can be opened
{
printf("error student");
}
while(!feof(s_ans))
{
for(j=0;j<20;j++)
{
fscanf(s_ans,"%s",arrs[j]);
}
}
printf("ReadStudent\n");
for(i=0;i<20;i++)
{
printf("%d\t %s\n",i+1,arrs[i]);
}
return arrs;
}
char* readcorrect()
{
FILE*c_ans;
int x,i;
static char arrc[20];
c_ans=fopen("CorrectAnswers.txt","r");
if (c_ans == NULL)//check if file can be opened
{
printf("error correct");
}
while(!feof(c_ans))
{
for(x=0;x<20;x++)
{
fscanf(c_ans,"%s",arrc[x]);
}
}
printf("ReadCorrect\n");
for(i=0;i<20;i++)
{
printf("%d\t %s\n",i+1,arrc[i]);
}
return arrc;
}
//Main
int main()
{
int i,j,n,x;
char* as_ans=readstudent();
char* ac_ans=readcorrect();
printf("Main");
for(i=0;i<20;i++)
{
printf("%s",as_ans[i]);
}
return 0;
}

Function casts itself c, after it has been casted twice

I've got a university project where I have to write a database of workers. I decided to use dynamic array of structures:
struct data
{
char id[50];
char name[50];
char surname[50];
char account_num[50];
double net_pension,taxed_pension;
};
int main()
{
int current_size=0;
struct data *database;//creating a table
database=(struct data*)malloc(1*sizeof(struct data));//memory allocation
menu(database);//running menu
return 0;
}
function menu
void menu(struct data *database)
{
int current_size=1;
int input=0;
char inpt[512];
do
{
printf("Input function or input help for list of avaible commands \n");
fgets(inpt,511,stdin);
input=mod_input(inpt);
if(input==404)
{
printf("Function does not exist \n");
}
else if(input==1)
{
print_result(database,current_size);
}
else if(input==2)
{
add_element(database,&current_size);
}
else if(input==3)
{
modify_element(database,current_size);
}
else if(input==4)
{
sort_table(database, current_size);
}
else if(input==5)
{
search(database,current_size);
}
else if(input==6)
{
hilfe();
}
else if(input==7)
{
search_by_col(database,current_size);
}
input=8;
}
while(input!=0);
}
decides what we want to do, for example writing "add" will start my problematic function, which is supposed to add new records
void add_element(struct data *database,int *size)
{
int subflag=0;
char inpt[50];
int place=((*size)-1);
int pass=(*size);
printf("%i",pass);
if((*size)!=1)
{
modify_element(database,(*size));
}
do
{
printf("Input unical ID \n");
fgets(inpt,50,stdin);
if(does_exist(inpt,database,pass)==1)
{
subflag=1;
strncpy(database[place].id,inpt,50);
}
else
{
printf("ID exists");
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input name \n");
fgets(inpt,50,stdin);
if(is_word(inpt)==1)
{
subflag=1;
strcpy(database[place].name,inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input surname \n");
fgets(inpt,50,stdin);
if(is_word(inpt)==1)
{
subflag=1;
strcpy(database[place].surname,inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input account number \n");
fgets(inpt,50,stdin);
if(is_accnum(inpt)==1)
{
subflag=1;
strcpy(database[place].account_num,inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input net gain \n");
fgets(inpt,50,stdin);
if(is_num(inpt)==true)
{
printf("%d",atof(inpt));
subflag=1;
database[place].net_pension=atof(inpt);
}
}
while(subflag==0);
subflag=0;
do
{
printf("Input taxed gain \n");
fgets(inpt,50,stdin);
if(is_num(inpt)==true)
{
subflag=1;
database[place].taxed_pension=atof(inpt);
}
}
while(subflag==0);
printf("record added \n");
if((*size)==1)
(*size)++;
}
function modify_size reallocs memory, does_exist ensures, that id's are unique, is acc_num, num and word checks input for given rules. They all work perfectly when you use function first time. But after you try to add second one "record added" does not display and function add runs from the beginning. I ahve no idea why. That is the main problem. Secondary one is menu, because when you input "print" it runs add_element. Code that converts input is:
int mod_input(char function[])
{
printf(function);
if(strcmp(function,"modify")==1)
return 3;
else if(strcmp(function,"sort")==1)
return 4;
else if(strcmp(function,"search")==1)
return 5;
else if(strcmp(function,"help")==1)
return 6;
else if(strcmp(function,"add")==1)
return 2;
else if(strcmp(function,"print")==1)
return 1;
else if(strcmp(function,"search_by_column")==1)
return 7;
return 404;
}
Thank you in advance for help. Also I know that some parts could be done better, but for now, I try to just force it to work.
whole programme
lab3.c and header
Intuitively, what you need to do is pass around a pointer to a pointer to your array, not just a pointer to it. And that's what BLUEPIXY was trying to get at in a comment.
The problem is that if you do x = realloc(y, new_size), there's no guarantee that x will be equal to y.
In particular, database = realloc(database, new_size) inside a subroutine may leave the subroutine with a different value for database than the one passed in as an argument. The caller still has the old value for database.
The results are undefined, and may include worse than what you got.
What you want is something like
struct data *datap;
struct data **database = &datap;
*database = malloc(sizeof(struct data))
With corresponding changes all the way down - basically pass database, and set *database = realloc(...) when you get to that stage.
Also, make sure you update *size appropriately at the same time.

Allocation to Pointers

I work with char ****pCourses
int Courses(char ****pCourses, int ****pGrades, int **pCount, int *count)
{
char *buffer=NULL;
char letter;
int j=0, i;
int size=20;
int countCourse=0, sumCourses=0;
buffer=(char *)malloc(size*sizeof(char));
do
{
scanf("%c",&letter);
}while(letter==32);
while(letter!=10)
{
while(letter!=',')
{
//in case we need to expend the buffer
if(j>size)
{
size*=2;
buffer=(char *)realloc(buffer,size*sizeof(char));
}
buffer[j]=letter;
j++;
//The new letter from the name of course
scanf("%c",&letter);
}
//The end of the name of course
buffer[j]='\0';
j=0;
if(countCourse==0)
{
*pCount=(int *)realloc(*pCount, ((*count)+1)*sizeof(int));
(*pCount)[*count]=1;
}
else
(*pCount)[*count]++;
//Add the course's name to the system
*pCourses=(char ***)realloc(*pCourses, ((*count)+1)*sizeof(char ***));
(*pCourses)[*count]=(char **)realloc((*pCourses)[*count],(countCourse+1)*sizeof(char *));
((*pCourses)[*count])[countCourse]=(char *)malloc(strlen(buffer)+1);
strcpy(((*pCourses)[*count])[countCourse], buffer);
countCourse++;
scanf("%c",&letter);
}
free(buffer);
return 0;
}
while running I get a problem because of the next line:
(*pCourses)[*count]=(char **)realloc((*pCourses)[*count],(countCourse+1)*sizeof(char *));
that leads me to this part (from dbgheap.c):
{
while (nSize--)
{
if (*pb++ != bCheck)
{
return FALSE;
}
}
return TRUE;
}
does someone know what it means or why does this happen?
I think you've already been told what the problem is. All the alloc-type functions can fail and you should test for that and ideally write code that is robust enough to code with a failure.
Note that repeatedly using realloc() is not a good idea. If you expect to have to repeatedly add ( or remove ) data then you should be using a different structure, like a linked list or tree, which are designed to allow adding and removing data on the fly.

Multithreading going throught an array of struct in C

I have wrote a program that receives as input a text file and return as output another text file.
The text file is created with a script(python) inside a 3D app (Blender) , and it contains a list of vertex that are part of a square mesh. The program receives that data, stores it in a struct, and return a list of vertex that forms a smaller square. Than, the 3D app, again with a script, reads this vertices and separate them from the original mesh. Doing this several times, the original mesh will be divided in many squares of the same area.
BY NOW, IT WORKS ;)
But is terribly low.. When doing it on 200k vertices it takes a while, but running it on 1kk vertices it takes ages
Here the source:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct{
int index;
float x,y,z;
} vertex;
vertex *find_vertex(vertex *list, int len)
{
int i;
vertex lower,highter;
lower=list[0];
highter=list[1];
//find the lower lefter and the upper righter vertices
for(i=0;i<len;i++)
{
if ((list[i].x<=lower.x) && (list[i].y<=lower.y))
lower=list[i];
if ((list[i].x>=highter.x) && (list[i].y>=highter.y))
highter=list[i];
}
vertex *ret;//create a pointer for returning 2 structs
ret=(vertex*)malloc(sizeof(vertex)*2);
if (ret==NULL)
{
printf("Can't allocate the memory");
return 0;
}
ret[0]=lower;
ret[1]=highter;
return ret;
}
vertex *square_list_of_vertex(vertex *list,int len,vertex start, float size)
{
int i=0,a=0;
unsigned int *num;
num=(int*)malloc(sizeof(unsigned int)*len);
if (num==NULL)
{
printf("Can't allocate the memory");
return 0;
}
//controlls if point is in the right position and adds its index in the main list in another array
for(i=0;i<len;i++)
{
if ((list[i].x-start.x)<size && (list[i].y-start.y<size))
{
if (list[i].y-start.y>-size/100)//it was adding also wrong vertices. This line is to solve a bug
{
num[a]=i;
a++;//len of the return list
}
}
}
//create the list with the right vertices
vertex *retlist;
retlist=(vertex*)malloc(sizeof(vertex)*(a+1));
if (retlist==NULL)
{
printf("Can't allocate the memory");
return 0;
}
//the first index is used only as an info container
vertex infos;
infos.index=a+1;
retlist[0]=infos;
//set the value for the return pointer
for(i=1;i<=a;i++)
{
retlist[i]=list[num[i-1]];
}
return retlist;
}
//the function that pass the data to python
void return_funct_1(vertex lower,vertex highter)
{
FILE* ret;
ret=fopen("max_min.txt","w");
if (ret==NULL)
{
printf("Error opening the file\n");
return;
}
fprintf(ret,"%i\n",lower.index);
fprintf(ret,"%i\n",highter.index);
fclose(ret);
}
//the function that pass the data to python
void return_funct_2(vertex *squarelist)
{
FILE* ret;
int i,len;
ret=fopen("square_list.txt","w");
if (ret==NULL)
{
printf("Error opening the file\n");
return;
}
len=squarelist[0].index;
for(i=1;i<len;i++)
{
//return all the informations
//fprintf(ret,"%i %f %f %f\n",squarelist[i].index,squarelist[i].x,squarelist[i].y,squarelist[i].z);
//just return the index(it's enought for the python script)
fprintf(ret,"%i\n",squarelist[i].index);
}
fclose(ret);
}
//argv:
//function[1/2] number_of_vert(int) size_of_square(int) v_index(int) v_xcoord(float) v_ycoord(float) v_zcoord(float)...
//example of file: 2 4 2 0 1 2 3 1 1 2 3 2 1 2 3 3 1 2 3 4 1 2 3 //function 1, number of ver=4, size=2 and then the 4 vertex with their coords
int main(int argc, char *argv[])
{
if(argc==1)
{
printf("%s need a path to a vectorlist file\n",argv[0]);
return 0;
}
FILE* input;
input=fopen(argv[1],"r");
if (input==NULL)
{
printf("Error opening the file\n");
return(0);
}
int func=0,i=0,a=0,u=0;
char read;
char* argument;
argument=(char*)malloc(sizeof(char)*50);//yeah, i know, i should use list instead of an array, but when i first coded this i was quite in hurry (and i'm still learning )
//get the first paramater in the file
argument[0]=fgetc(input);
argument[1]='\0';
func=atoi(argument);
//skipp the space
read=fgetc(input);
//get the number of vertices;
i=0;
do {
read=fgetc(input);
argument[i]=read;
i++;
}while(read!=' ' && !feof(input) );
//set the end of the string
argument[i]='\0';
//set the variable to the correct integer value;
int vnumber=atoi(argument);
i=0;
do {
read=fgetc(input);
argument[i]=read;
i++;
} while(read!=' ' && !feof(input));
//set the end of the string
argument[i]='\0';
float sqsize=atof(argument);
vertex *list;
//allocate memory in the array to fit the number of vertex needed
list=(vertex*)malloc(sizeof(vertex)*vnumber);
//control if the memory get allocated
if (list==NULL)
{
printf("Can't allocate the memory");
return 0;
}
//do the cycle for each vertex
for(u=0;u<vnumber;u++)
{
//read the number and assign it to the proper value of the vertex
for(a=0;a<4;a++)
{
i=0;
do
{
read=fgetc(input);
argument[i]=read;
i++;
} while(read!=' ' && !feof(input));
argument[i]='\0';
if(a==0)
list[u].index=atoi(argument);
if(a==1)
list[u].x=atof(argument);
if(a==2)
list[u].y=atof(argument);
if(a==3)
list[u].z=atof(argument);
}
}
//close the file
fclose(input);
if (func==1)
{
//find the lowest vertex and the higtest vertex
vertex lower;
vertex highter;
vertex *lohi;
lohi=(vertex*)find_vertex(list, vnumber);
lower=lohi[0];
highter=lohi[1];
free(lohi);
return_funct_1(lower,highter);//the function that return the data to python
return 1;
}
if(func==2)
{
//find the list to return
vertex *lohi;
lohi=(vertex*)find_vertex(list, vnumber);
vertex lower;
lower=lohi[0];
free(lohi);
return_funct_2(square_list_of_vertex(list,vnumber, lower, sqsize));//the function that return the data to python
return 1;
}
printf("Function argument was wrong: nothing was done\n");
}
I would really appreciate any help for making this multithreaded.. It takes ages to work on really big data(today i've tried with a 50mb text file, and after 20 mins it had run only 30 times(on the 26000 i needed)), and since quite all pc that will use this will have at least 4 cores, i would really like to get it multithreaded!
Thanks in advice! :)
Ps: if you need, i can post the python script code too, but it's quite full of calls to the internal api of the program, so i don't really know if it would be usefull.
I am not going to work specifically through your code but your algorithm may be able to apply Map and Reduce.
This is an article of how you can use it in C:
http://pages.cs.wisc.edu/~gibson/mapReduceTutorial.html
When I profile your code running over a sample dataset of 2 million random vertexes, with the source file preloaded into the page cache the bottleneck is the conversion of strings to floats (it still runs in only 5 seconds, though - so it's not that slow).
It is possible to multithread the conversion of strings to floats, and with careful coding you will get some gains this way. However, you will get much more bang for your buck if instead you change the Python code to write the floating point numbers in a binary format that can be directly loaded by the C code (with fread()). I believe you can use struct.pack on the Python side to achieve this.
The processing part of your code can certainly be improved too, but until it is the bottleneck I wouldn't worry about it.

Resources