-1

Im trying to read in some data from a file (ultimately into a structure, but not important for now) and to ensure that this file has equal amount of data on each line. Each line can have words or numbers though so I've converted one line of a file into one big string. I then try and split this string into tokens using strtok and commas (which separate the data) as delimiters. But how can i count the amount of tokens that exist between commas. I've tried to count the amount of commas on each line but for some reason it is not behaving as it i expect it to. Each line in the file has 5 pieces of data, all split by commas, so there should be 4 commas on each line.

 while (fgets(string, sizeof(string), f)) {
    input = fgetc(f);
        if(input == ','){
            i++;        
        }
        else if (input == ' '){
            printf("Error");
            exit(0);
        }
   }

    if(i % 4 != 0){
        printf("Error");
        exit(0);
    }   

Here i am trying to count the amount of commas on every line (and if theres a space on the file line, it should show an error, as I ONLY want commas dividing the data). Finally after fgets stops reading, I want to see if the "i" variable is a multiple of 4. Im sure there is a more efficient and user friendly way to do this though but I cant think of one.

Quick question as well: does the fgetc run through every character on the line before the rest of the commands continue, or as soon as a comma is encountered, my program will move on the next loop?

Thank you!

stellarhawk 34
  • 133
  • 1
  • 3
  • 11
  • 1
    The data read by `fgets(string, sizeof(string), f)` into `string` is not used. It this your intent? – chux - Reinstate Monica Mar 22 '16 at 02:15
  • 2
    Why are you using both `fgets()` *and* `fgetc()`? – EOF Mar 22 '16 at 02:15
  • a simple way to count the commas in a line and abort on a space is to iterate through the line, similar to: `size_t commaCount=0; for( size_t i=0; string[i]; i++) { if( ',' == string[i] ) { commaCount++; } else if( ' ' == string[i] ) { //abort due to space } }` – user3629249 Mar 22 '16 at 02:47
  • he function: fgets() only stops on a newline or a EOF. or the input buffer only has a single byte left to fill (as defined by the second parameter). So fgets() will not stop on a space or comma (unless that is what filled the input buffer). so the call to fgetc() is (normally) getting the first character from the next line in the input file. Probably not what you want. – user3629249 Mar 22 '16 at 02:50
  • @user3629249 , the reason I dont like your suggestion is because for example one line can have 5 commas and the next line might have 3. This algorithm will fail to discover that there arent 4 on one line. – stellarhawk 34 Mar 22 '16 at 09:11
  • your question did not say to verify 4 commas, rather it said to count the commas and abort on a space. You can easily add a 'if' the 'commaCount' not equal 4, before reading the next line – user3629249 Mar 22 '16 at 16:53

1 Answers1

0

To count commas at each line of file you need to know exact line delimiter in your file. Then you may iterate over file until end-of-file reached and count commas within lines.

In following example i assume '\n' is a line delimiter.

#define DESIRED_COMMAS_COUNT 4
int commas_per_line = 0;
bool prev_is_comma = false;
int c;
while ((c = fgetc(f)) != EOF) //This expression reads one characters from file and checks for end-of-file condition
{
  switch(c)
  {
    case ',': 
      commas_per_line++; 
      if (prev_is_comma)
      {
        printf("Two successive commas! Empty element in line\n");
        exit(1);
      }
      prev_is_comma = true;
      if (commas_per_line > DESIRED_COMMAS_COUNT)
      {
        printf("Error: too many commas at line. At least %d.\n", commas_per_line);
        exit(1);
      }
      break;
    case ' ': 
      printf("Error: space encountered!\n"); 
      exit(1);
    case '\n': 
      if (commas_per_line != DESIRED_COMMAS_COUNT)
      {
        printf("Error: too low commas (%d)", commas_per_line);
        exit(1);
      }
      if (prev_is_comma)
      {
        printf("Line ends with comma: no last element in line\n");
        exit(1);
      }
      commas_per_line = 0; 
      break;
    default:
      prev_is_comma = false;
  }
}
if ((commas_per_line != DESIRED_COMMAS_COUNT) && //check commas count for last line in file
    (commas_per_line != 0))
{
  printf("Error: too low commas (%d)", commas_per_line);
  exit(1);
}
  • 1) using `feof()` for checking for end of file is a very bad idea as it does not work as this answer is assuming it does. 2) `fgetc()` returns a `int` not a `char`. 3) suggest: `int c; while( (c = fgetc()) != EOF ) – user3629249 Mar 22 '16 at 16:50