LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C code to read in a tab deliminated file (https://www.linuxquestions.org/questions/programming-9/c-code-to-read-in-a-tab-deliminated-file-4175484566/)

pople 11-14-2013 09:08 AM

C code to read in a tab deliminated file
 
So I've been working on this code for a bit but I cannot seem to get it to function properly. I think there is something wrong with my variable types due to the compiler error. The purpose of this code is to read in a .xyz coordinate file and assign varialbes in three arrays whose indicies correspond to the atom number.

Code:

3$ gcc LJ_CUDA_D1.c -o LJ_CUDA_D1.o
LJ_CUDA_D1.c:48:6: warning: conflicting types for ‘f2input’ [enabled by default]
LJ_CUDA_D1.c:24:4: note: previous implicit declaration of ‘f2input’ was here

Here is my code:
Code:

#include<stdio.h>
#include<stdlib.h>

main(int argc, char *argv[]){
  int i;
 FILE *fp;
 char *inputfile = "-i";
 //printf("inputfile switch is %s\n",inputfile);
    for(i=1;i<argc;i++){
      printf("argv[%d] = %s\n", i, argv[i]);
      //if(strcmp(argv[i],inputfile) != 1){
      if(*argv[i] == *inputfile){
        ++i;
              if((fp = fopen(argv[i], "r")) == NULL){
                printf("Error in opening file %s\n", *argv);
                return 1;
              }
              else {
                //fp = fopen(argv[i], "r"); // No sense repeating the same function.
                printf("%s is open\n",argv[i]);
          //filecopy(fp, stdout); // debugging line
          f2input(fp);
          //printf("Atom one coodinates x %f, y %f, and z %f\n",atomx[1],atomy[1],atomz[1]);
          fclose(fp);
          return 1;
              }
      }
    }
    return 0;
}
void finput(FILE *ifp)
// use atof() here!!!
{
  char str[128], c;
  int row = 1;
  while(!feof(ifp))
    {
      if(row == 1){
        if(fgets(str, '\t', ifp)){
          printf("%s", str);
          ++row;
        }
      }
  }
}
void f2input(FILE *ifp)
{
  int N;
  char c;
  N = 0;
  while((c = getc(ifp)) != EOF){
      if(c == '\n')
            ++N; //Indicates the numnber of atoms based on # of lines in the file.
        }
  int atom = 0;
  float *atomx = malloc(N*sizeof(float));
  float *atomy = malloc(N*sizeof(float));
  float *atomz = malloc(N*sizeof(float));
  while(fscanf(ifp, "%f %f %f", &atomx[atom], &atomy[atom], &atomz[atom]) != EOF){
    fscanf(ifp, "%f %f %f", &atomx[atom], &atomy[atom], &atomz[atom]);
    ++atom;
  }
  printf("Atom one coodinates x %f, y %f, and z %f\n",atomx[1],atomy[1],atomz[1]);
}
/* void fileinput(FILE *ifp) */
/* { */
/*  int N, column, atom; */
/*  char c; */
/*  column == 1; */
/*  N = 0; */
/*  atom = 0; */
/*    while((c = getc(ifp)) != EOF){ */
/*      if(c == '\n') */
/*            ++N; //Indicates the numnber of atoms based on # of lines in the file. */
/*        } */
/*    double *atomx = malloc(N*sizeof(double)); */
/*    double *atomy = malloc(N*sizeof(double)); */
/*    double *atomz = malloc(N*sizeof(double)); */
/*    while((c = getc(ifp)) != EOF){ */
/*      if(column == 1){ */
/*        //try atof here */
/*                double c = atomx[atom]; */
/*          if(c == '\t') */
/*            ++column; */
/*      }      if(column == 2){ */
/*              double c = atomy[atom]; */
/*        if(c == '\t') */
/*          ++column; */
/*      } */
/*      if(column == 3){ */
/*              double c = atomz[atom]; */
/*        if(c == '\n'){ */
/*          column = 1; */
/*          ++atom; */
/*        } */
/*      } */
/*    } */
/*    printf("Atom one coodinates x %f, y %f, and z %f\n",atomx[1],atomy[1],atomz[1]); */
/* } */
/* filecopy: copy file ifp to file ofp. For debuggage */
void filecopy(FILE *ifp,FILE *ofp)
{
  int c;
 
  while((c = getc(ifp)) != EOF)
    putc(c, ofp);
}

I have been experimenting with different methods but so far none have worked. Any help would be appreciated. The output of the current code is:

Code:

$ ./LJ_CUDA_D1.o -i test.txt
argv[1] = -i
test.txt is open
Atom one coodinates x 0.000000, y 0.000000, and z 0.000000

and the test.txt file is:
Code:

1.0000    2.000    1.5
3.0000    5.000    1.4
4.0000    3.000    1.3


mina86 11-14-2013 09:43 AM

The problem is that you used a function before declaring (or defining) it. Add
Code:

void f2input(FILE *ifp);
line above main function and this warning should go away.

Also, compile with -Wall to get warning when you implicitly declare a function.

pople 11-14-2013 09:53 AM

That took care of the error. However fscanf() still did not assign any values to the atomx, atomy, atomz arrays. Thus, I still get the same output as before. Any thoughts?

mina86 11-14-2013 10:16 AM

Code:

if(fgets(str, '\t', ifp))
What is this supposed to be? The second argument to fgets is the length of the buffer not character you want to stop reading at.

Code:

while(fscanf(ifp, "%f %f %f", &atomx[atom], &atomy[atom], &atomz[atom]) != EOF){
EOF is used with getchar() and related functions, not fscanf. fscanf returns number of read and assigned values. You want to compare to 3 (since this is how many variables you have).

PS. It would be helpful if you provided a nicely formatted file. By nicely formatted I mean at least the two: (i) no commented code – if it's not executed, just don't include it, and (ii) use consistent indentation. (i) also goes with the fact that your code should be minimal that shows the issue you're encountering.

pople 11-14-2013 05:12 PM

So here is a cleaner revised version of the code I have been working on:

Code:

#include<stdio.h>
#include<stdlib.h>
void fileinput(FILE *ifp)
{
  int N, column, atom;
  int c;
  column = 1;
  N = 0;
  atom = 0;
  char str[256];
  double * atomx = malloc(N*sizeof(double));
  double * atomy = malloc(N*sizeof(double));
  double * atomz = malloc(N*sizeof(double));
  while((c = getc(ifp)) != EOF){
    if(column == 1){
      fgets(str,256,ifp);
      atomx[atom] = atof(str);
      if(c == '\t')
        ++column;
    }
    if(column == 2){
      fgets(str,256,ifp);
      atomy[atom] = atof(str);
      if(c == '\t')
        ++column;
    }
    if(column == 3){
      fgets(str,256,ifp);
      atomz[atom] = atof(str);
      if(c == '\t'){
        column = 1;
        ++atom;
      }
    }
  }
  printf("Atom one coodinates x %f, y %f, and z %f\n",atomx[1],atomy[1],atomz[1]);
}
main(int argc, char *argv[]){
  int i;
 FILE *fp;
 char *inputfile = "-i";
    for(i=1;i<argc;i++){
      if(*argv[i] == *inputfile){
        ++i;
              if((fp = fopen(argv[i], "r")) == NULL){
                printf("Error in opening file %s\n", *argv);
                return 1;
              }
              else {
          fileinput(fp);
          fclose(fp);
          return 1;
              }
      }
    }
    return 0;
}

My goal in the fileinput() function is to open and read in to the arrays the tab deliminated values in the input file. However with the diagnostic printf statement the output is the same as before no values are assigned:

Code:

$ ./input.o -i ./test.txt
Atom one coodinates x 0.000000, y 0.000000, and z 0.000000

I'm still not sure why this is not working. I'd really appreciate any help.

mina86 11-15-2013 07:01 AM

Code:

while((c = getc(ifp)) != EOF){
You are consuming a character and then ignoring it. What you really want to do is something like:
Code:

while (fgets(str, sizeof str, ifp)) {
    sscanf("%f %f %f", atomx + atom, atomy + atom, atomz + atom);
    ++atom;
}

with additional error checking. Read on fgets to see how to check whether a whole line was read.

Code:

if(*argv[i] == *inputfile){
To compare strings use strcmp. You may also take a look at getopt.


All times are GMT -5. The time now is 08:57 PM.