martedì 2 febbraio 2016

I sing the parsing song

One simple format to store your atomic positions is .xyz format.
The file starts with a number (N) that tells how many atoms (and how many rows) will follow.
The remaining file is made of 4 columns with type of atom and 3 cordinates. An example is the following:

4

Pd 1 1 2.
Pd 3 1.4 1.
Pd 1 4.3 11
Pd 4 1.2 3.

Now, for every simulation or elaboration, i need to read these kind of files and, preferably, create 4 arrays one of strings and the other 3 of float.
The best thing would be to have a separate function outside the main, in order to call it when needed.
So the values must be passed by reference and not by value, using C pointers. 
The problems arise because of the clumsy way C handles strings, which basically are arrays of char.
Moreover, I do not expect the atom type to be a string of more than 5 characters, so what I need to do when passing by reference my array of strings (which is a Nx6 matrix of char) is to send a triple pointer to the function that is, actually, a double pointer to a string and everything blows up without a careful use of & and *.
Here's the result.
That's it.  It took time to get it so simply and now I am happy and I wanted to share this in order to avoid a lot of complications to those interested.



  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>


  4. void  parserxyz(char *fileneeded, double **atomx, double **atomy, double **atomz, char (**atomtype)[5], unsigned int *N)
  5. {
  6. FILE * fp;
  7. unsigned int i;
  8. fp = fopen(fileneeded, "r");
  9. if (fp == NULL) {
  10.  exit(EXIT_FAILURE);
  11. }
  12. fscanf(fp,"%u", N);
  13. *atomx = (double*) malloc(sizeof(double)*(*N));
  14. *atomy = (double*) malloc(sizeof(double)*(*N));
  15. *atomz = (double*) malloc(sizeof(double)*(*N));
  16. *atomtype= malloc(5*sizeof(char) * (*N));
  17. for (i=0; i<(*N); ++i)
  18. {
  19. fscanf(fp,"%s %lf %lf %lf", (*atomtype)[i],  &(*atomx)[i], &(*atomy)[i], &(*atomz)[i] ); 
  20. }

  21. fclose(fp);

  22. }

Nessun commento:

Posta un commento