1

I am trying to write a code in C so that if I have a file reg2.dat as such:

5.1 3.5 1.4
4.9 3 1.4
4.7 3.2 1.3
4.6 3.1 1.5
5 3.6 1.4

Then, I can 1) determine the number of rows (in this case 5), 2) determine the number of columns (in this case 3), 3) write all 15 values in an array X.

I have my code working for the first two goals. However, I cannot get the array X to contain the values (5.1, 3.5, 1.4, 4.9, 3, 1.4, 4.7, 3.2, 1.3, 4.6, 3.1, 1.5, 5, 3.6, 1.4). I am getting a few errors as well.

Below is my complete and ordered code:

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

int getCol(char *myStr);
int getRow(char *fileName);
int assignX(int nCol, int nRow, double *X, char *fileName);

int main(){
   FILE *f;
   char myStr[1000];
   int strL;
   int nCol;
   int nRow;
   char *fileName = "reg2.dat";
   double *X;

   f = fopen(fileName, "r");
   if (f == NULL) perror ("Error opening file");
   else {
     if (fgets(myStr, 1000, f) != NULL )
       puts(myStr);
     fclose(f);
   }

   strL = strlen(myStr);
   nCol = getCol(myStr);
   nRow = getRow(fileName);
   printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);

   X = (double *) malloc(sizeof(double) * (nRow* nCol));

   return 0;
}

The helper function that does not work follows...

int assignX(int nCol, int nRow, double *X, char *fileName){
  int i=0;
  int j;
  char *string;
  FILE *f;
  f = fopen(fileName, "r");

  while(!feof(f)){  
    string = fgets(f);
    for (j=0; j<nCol; j++){
       strcpy(X[i], strtok(string, " "));
       i++;
    }  
  }

  for (i=0;i<(nRow*nCol);i++){
    printf("%d\n", X[i]);
  }
}

The helper functions that do work follows...

int getCol(char *myStr){
    int length,i,count=0;
    char prev;
    length=strlen(myStr);
    if(length > 0){
      prev = myStr[0];
    }
    for(i=0; i<=length; i++){
      if(myStr[i]==' ' && prev != ' '){
        count++;
      }
      prev = myStr[i];
    }
    if(count > 0 && myStr[i] != ' '){
        count++;
    }
    return count;
}

int getRow(char *fileName){
  char ch;
  int count=0;
  FILE *f;
  f = fopen(fileName, "r");

  while(!feof(f)){
    ch = fgetc(f);
    if(ch == '\n')
    {
      count++;
    }
  }
return count;
}

I have tested that the last two helper functions getRow and getCol work, and return values of nRow = 5 and nCol = 3. I am only keeping them in here in case it could possibly cause the error (which I doubt). The errors appear to come from the first helper function assignX. Here are the errors when I run:

gcc -ansi -pedantic readReg.c -o readReg -llapack -lblas -lgfortran

Errors:

readReg.c: In function ‘assignX’:
readReg.c:52: warning: passing argument 1 of ‘fgets’ from incompatible pointer type
/usr/include/stdio.h:626: note: expected ‘char * __restrict__’ but argument is of type ‘struct FILE *’
readReg.c:52: error: too few arguments to function ‘fgets’
readReg.c:54: error: incompatible type for argument 1 of ‘strcpy’
/usr/include/string.h:128: note: expected ‘char * __restrict__’ but argument is of type ‘double’

Thank you for your help.

1
  • The fgets() function takes three arguments, and the third is the file pointer, not the first. Also, while (!feof(file)) is always wrong. Also copying strings into an array of double is dubious; are you looking for atof() or something similar. You look like you have memory management issues too. Commented Mar 22, 2015 at 23:38

2 Answers 2

1

Number of issues

  1. Instead of char *string; ... while(!feof(f)){ string = fgets(f);, use char string[1000]; while(fgets(string, sizeof string, f) != NULL) {. Learner code rarely uses feof(). Check fgets() return value instead.

  2. int getRow(char *fileName) opens, but does not close f. Add fclose(f).

  3. main() appears to only read 1 line of the file.

There is more, but GTG

Sign up to request clarification or add additional context in comments.

Comments

0

There are other few issues, but the compiler fails because of this line:

string = fgets(f); 

fgets cannot be called this way, since there are missing arguments:

char * fgets (char *s, int count, FILE *stream)

The other mistake your compiler is complaining about is this line in your assignX function:

   strcpy(X[i], strtok(string, " "));

You have this declaration in your main:

double *X;

While to call strcpy you need to follow this template:

char * strcpy (char *restrict to, const char *restrict from)

Moreover, You declared your X to be a pointer not an array, so trying to access X[i] would in any case lead to any kind of errors: undefined behaviour (if you are in a context that allows you to access the memory locations in the same block as X), segmentation faults and failures at compile time.

The array declaration char a[6] requests that space for six characters be set aside, to be known by the name a''. That is, there is a location nameda'' at which six characters can sit. The pointer declaration char *p, on the other hand, requests a place which holds a pointer, to be known by the name ``p''. This pointer can point almost anywhere: to any char, or to any contiguous array of chars, or nowhere

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.