• C

C Programming: Reading from a file

I created a socket (using C), and made it into a daemon. I now need to read from a config file in order for the program to make a decision on how to handle requests.

How do I read from the below config file, and interpret the configuration? See the config file below. I can only use open(2), read(2), etc.

My thoughts:
* Read file char by char until you encounter '\n'. If first char is '#' or '\n', skip to next line.
* Save line to a char pointer.
* Process the line by checking for isspace() to detect the end of each column in config file.
* Save all three columns into a struct.
* Add struct to array of structs.

Problem with this idea:
After saving the first line, how do I read the next line in the config file?

Does my strategy even make sense or is it stupid? Is there maybe a better way?

# Example Configuration File for deflect:  
#     deflect:  Daemon for HTTP Egress, Filtering, Load balancing, and Caching Trivially
#
# URL-prefix                           Disposition               Host list

http://www.csun.edu/               redirected              130.166.238.195, redwing.csun.edu
http://facebook.com/                filtered
http://www.csun.edu/~steve   cached                     www.csun.edu

# Note that any URL that is not covered by any rule is transferred through the system 
# without any additional processing.

Open in new window

LVL 8
pzozulkaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenDBACommented:
Hi pzozulka,

If you're limited to low-level I/O (open, read, etc.) I'd consider reading the entire file at once.

-- Read the file size from the O/S.
-- Allocate a buffer 1 byte longer than the file.
-- Read the entire file into the buffer.
-- Scan the buffer, converting all \r\n characters to zero.

You now have all of the lines of the file at your easy disposal.


Good Luck,
Kent
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
pzozulkaAuthor Commented:
I lost you here.
-- Scan the buffer, converting all \r\n characters to zero.

Sorry I'm a beginner. Can you provide further details here.
0
Kent OlsenDBACommented:
Sure.

  char *Buffer;
  char *ch;

  int    FileSize;

  Buffer = (char*) malloc (FileSize+1);
  read (file, Buffer, FileSize);
  Buffer[FileSize] = 0;

  for (ch = Buffer; *ch; ++ch)
    if (*ch == '\r' || *ch == '\n')
      *ch = 0;



Now all of the lines in the file are in memory (starting at *Buffer*) and will behave as strings.  With the carriage return and line feed characters (end of lines) in the buffer you had one long string.
0
Managing Security Policy in a Changing Environment

The enterprise network environment is evolving rapidly as companies extend their physical data centers to embrace cloud computing and software-defined networking. This new reality means that the challenge of managing the security policy is much more dynamic and complex.

pzozulkaAuthor Commented:
Shouldn't we end all lines of the file with '\0' and not just 0?
0
pzozulkaAuthor Commented:
Also, how do I access line 5 of the buffer, for example? This what really gets me as part of my original question.
0
Kent OlsenDBACommented:
'\0' is zero.  :)  It's C syntax for "the character with the value of 0", but you can use either one where ever a character or integer zero is needed.

To access line 5, you'll need to build one more table, with a list of addresses.

You can make it all dynamic, but for simplicity, let's limit the number of lines that we'll track to 100.

  char *Buffer;
  char *ch;
  char *Lines[100];
  char LastChar;

  int    FileSize;
  int    LineCount;

  Buffer = (char*) malloc (FileSize+1);
  read (file, Buffer, FileSize);
  Buffer[FileSize] = 0;

  for (ch = Buffer; *ch; ++ch)
    if (*ch == '\r' || *ch == '\n')
      *ch = 0;

  
  for (LineCount = 0, LastChar = 0, ch = Buffer; ch - Buffer < FileSize; ++ch)
  {
    if (LastChar == 0)
    {
      if (*ch)  // ignore consecutive zero characters.
        Lines[LineCount++]++;
    }
    LastChar = ch;
  }

Open in new window


There's no sanity checks in it (like checking for LineCount < 100), but otherwise it should do the job.  It will take the address of the first character of each line and store it in Lines.  Afterwards, you can use Lines[line_number] to reference each line in the file.
0
pzozulkaAuthor Commented:
Thanks much.

I had to change it slightly to make it work. Very elegant code, and I don't think I'm at this level yet where I would be able to achieve this strategy/algorithm on my own.

Very nice.

I hope you don't mind me asking, I couldn't figure out what does "if(*ch)" evaluate to? This should be a Boolean expression to test if A == B or similar.
0
Kent OlsenDBACommented:
ch is a pointer.  The asterisk (*) is used to "dereference" the pointer.  That is, to take the value at the address instead of the address.

  char *ch

  ch = "This is an example";

ch now points to the 'T' that is the first character of the string.  Using (ch) in your program uses the address of 'T', while using (*ch) using the value at the pointer, 'T'.

  if(*ch)

That's shorthand for "if the value at the pointer is non-zero".  You could also write it as

  if (*ch != 0)
or
  if (*ch != '\0')


Good Luck!
Kent
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.