Search code examples
cposixnul

C reading a file with null in it


I'm working on a data file that contains a fixed number of characters followed by a colon and then a number. All of the first four characters can be anything from all nulls to all (char)255s.

However, when trying to read it, I'm having trouble determining the EOF.

If I use posix's read(2) like so:

ssize_t letters_read = read(fd, buf, 4);

Then letters_read is set to 0. The man page says that means I've reached an EOF; however, this is simply not true.

If I use fread(3) in a similar way, then I still get zero as a return value. Even when sending the file to feof(3), it says I'm at the end of file.

Now, if I just ignore the return values, then I'm able to continue reading the file and get further results.

How would I be able to read all four nulls and still be able to know when I've reached an eof?

A small excerpt of the file looks like this:

4
(null)(null)(null)(null):4
(null)(null)(null)(null):40
(null)(null)(null)(null):402
Af*8:3004

UPDATE
As per request, here is how I'm going about collecting data:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

void process_characters(char *data);


int main(int argc, char *argv[])
{
  char *input_file = argv[1];

  int opt = 0;

  int input_fd = open(input_file, O_RDONLY);

  FILE *temp_fd = fopen(input_file, "r");

  unsigned long character_size = 0;

  fscanf(temp_fd, "%l", character_size);


  char data[character_size];

  //gobble up the first line
  do
  {
    read(input_fd, data, 1);
    printf("%i\n", data[0]);
  } while(data[0] != '\n');

  size_t characters_read = 0;
  characters_read = read(input_fd, data, character_size);
  //while(feof(temp_fd) != 0)

  while(characters_read != 0)
  {

    //fread(data, sizeof(char), character_size, temp_fd);
    process_characters(data);
    ///gobble up the garbage
    do
    {
      read(input_fd, data, 1);
      printf("%i\n", data[0]);
    }while(data[0] != 10);

    characters_read = read(input_fd, data, character_size);
  }

  fclose(temp_fd);
  close(input_fd);
  return EXIT_SUCCESS;
}

Solution

  • This code:

      unsigned long character_size = 0;
    
      fscanf(temp_fd, "%l", character_size);
    

    ... has an invalid format specified, and needs to provide the variable address rather than its value. "%l" does not specify a type to read. Perhaps you want "%lu" which is for an unsigned long integer, which is how character_size is defined. character_size should be &character_size.

    However, there is no such (decimal) value at the beginning of the sample file you have provided, so it is unclear what this fscanf line is really supposed to do.

    (You claimed that using read as follow returns 0:

    ssize_t letters_read = read(fd, buf, 4);
    

    However, there is no such line in your code).