How to read strings from a file with comments

I

I. Myself

This is about reading the .ini files which are used in several of our
projects.

Currently, the actual read of each line of the file is with this statement:

fscanf(file, "%s %s", name, value); /* reads two strings from .ini
file */

This works, but it does not allow any comments to the right of the two
strings.
I would like to allow the .ini file to have long comments on the right.
Even better would be to allow additional lines of commentary also. The
computer should ignore the commentary, and just read the initial two
strings on each line.

Can anyone tell me how to do it?

Thanks,

Mitchell Timin

--
I'm proud of http://ANNEvolve.sourceforge.net. If you want to write software,
or articles, or do testing or research for ANNEvolve, let me know.

Humans may know that my email address is: (but remove the 3 digit number)
zenguy at shaw666 dot ca
 
I

Ian Collins

I. Myself said:
This is about reading the .ini files which are used in several of our
projects.

Currently, the actual read of each line of the file is with this statement:

fscanf(file, "%s %s", name, value); /* reads two strings from .ini
file */

This works, but it does not allow any comments to the right of the two
strings.
I would like to allow the .ini file to have long comments on the right.
Even better would be to allow additional lines of commentary also. The
computer should ignore the commentary, and just read the initial two
strings on each line.

Can anyone tell me how to do it?
Read the full line and check the first character (assuming you use
something like '#' for a comment marker). If it is a comment, ignore
the line, else replace your fscanf with scanf on the line you have just
read.
 
M

Mark McIntyre

Currently, the actual read of each line of the file is with this statement:

fscanf(file, "%s %s", name, value); /* reads two strings from .ini
file */

This works, but it does not allow any comments to the right of the two
strings.

Presumably you plan to delimit the comment somehow

SETTING=wibble #this bit is a comment

if so, use fgets() to read the line, then read up on sscanf() and
strchr().
Mark McIntyre
 
C

CBFalconer

I. Myself said:
This is about reading the .ini files which are used in several of
our projects.

Currently, the actual read of each line of the file is with this
statement:

fscanf(file, "%s %s", name, value); /* reads two strings from
.ini file */

This works, but it does not allow any comments to the right of the
two strings. I would like to allow the .ini file to have long
comments on the right. Even better would be to allow additional
lines of commentary also. The computer should ignore the
commentary, and just read the initial two strings on each line.

Can anyone tell me how to do it?

You can see a method in my id2id-20, function readidpairs. In
essence it is the following:

do {
ch = getident(leftwd, BUFMAX, idp, NULL);
ch = getident(rightwd, BUFMAX, idp, NULL);
ch = flushln(idp);
/* code to process the id pair */
} while (EOF != ch);

which needs the code for getident and flushln (both present). You
can get the complete package and source at:

<http://cbfalconer.home.att.net/download/id2id-20.zip>

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
J

Joe Estock

I. Myself said:
This is about reading the .ini files which are used in several of our
projects.

There are many pre-written utilities written in c which conform to the c
standards. Try a search on google, or if you prefer to use a home-rolled
version see below.
Currently, the actual read of each line of the file is with this statement:

fscanf(file, "%s %s", name, value); /* reads two strings from .ini
file */

fscanf wouldn't be my first choice for this.
This works, but it does not allow any comments to the right of the two
strings.
I would like to allow the .ini file to have long comments on the right.

This is rather trivial to accomplish. Read in one line of text (using
fgets perhaps). Pass a pointer to the buffer containing that line of
text to a new function you write (perhaps called remove_comments). Below
is an untested example. This assumes that your comments begin with the
'#' character and continue until EOL.

/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
size_t remove_comments(char **buffer)
{
char *p;

if(strchr(p, '#') == NULL)
return(0); /* no comment found */

for(p = *buffer; p != '\0' && p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return(strlen(p));
}
Even better would be to allow additional lines of commentary also. The
computer should ignore the commentary, and just read the initial two
strings on each line.

Ignoring multiple lines of comments would be a little more tricky, but
it certainly could be done. I'll leave you with finding a solution for
this task. The only thing you will need to do now is check for an empty
string after calling the above function. Additionally you can also
implement some sort of a trim function which removes all leading and
trailing whitespace from a given string.
Can anyone tell me how to do it?

Thanks,

Mitchell Timin

You're welcome and I hope that points you in the right direction. Again,
note that the above code is untested (however it should work).

Joe
 
K

Keith Thompson

Ian Collins said:
Read the full line and check the first character (assuming you use
something like '#' for a comment marker). If it is a comment, ignore
the line, else replace your fscanf with scanf on the line you have just
read.

I think you mean sscanf, not scanf.
 
S

stathisgotsis

Ο/Η Joe Estock έγÏαψε:
There are many pre-written utilities written in c which conform to the c
standards. Try a search on google, or if you prefer to use a home-rolled
version see below.


fscanf wouldn't be my first choice for this.


This is rather trivial to accomplish. Read in one line of text (using
fgets perhaps). Pass a pointer to the buffer containing that line of
text to a new function you write (perhaps called remove_comments). Below
is an untested example. This assumes that your comments begin with the
'#' character and continue until EOL.

/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
size_t remove_comments(char **buffer)
{
char *p;

if(strchr(p, '#') == NULL)
return(0); /* no comment found */

for(p = *buffer; p != '\0' && p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return(strlen(p));
}

Maybe a better (and working) version would be:

size_t remove_comments(char *buffer)
{
char *p;

if(strchr(buffer, '#') == NULL)
return strlen(buffer); /* no comment found */

for(p = buffer; *p != '\0' && *p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return strlen(p);
}

And one could even avoid the final strlen() call by calculating the
string length in the previous loop.
 
R

RSoIsCaIrLiIoA

/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
size_t remove_comments(char **buffer)
{
char *p;

if(strchr(p, '#') == NULL)
return(0); /* no comment found */

for(p = *buffer; p != '\0' && p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return(strlen(p));
}

if *p==0 then strlen(p)==0
 
S

stathis gotsis

Ï/Ç Joe Estock Ýãñáøå:
There are many pre-written utilities written in c which conform to the c
standards. Try a search on google, or if you prefer to use a home-rolled
version see below.


fscanf wouldn't be my first choice for this.


This is rather trivial to accomplish. Read in one line of text (using
fgets perhaps). Pass a pointer to the buffer containing that line of
text to a new function you write (perhaps called remove_comments). Below
is an untested example. This assumes that your comments begin with the
'#' character and continue until EOL.

/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
size_t remove_comments(char **buffer)
{
char *p;

if(strchr(p, '#') == NULL)
return(0); /* no comment found */

for(p = *buffer; p != '\0' && p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return(strlen(p));
}

Maybe a better (and working) version would be:

size_t remove_comments(char *buffer)
{
char *p;

if(strchr(buffer, '#') == NULL)
return strlen(buffer); /* no comment found */

for(p = buffer; *p != '\0' && *p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return strlen(buffer);
}
 
B

Ben C

/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
[...]
Maybe a better (and working) version would be:

size_t remove_comments(char *buffer)
{
char *p;

if(strchr(buffer, '#') == NULL)
return strlen(buffer); /* no comment found */

for(p = buffer; *p != '\0' && *p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return strlen(buffer);
}

Or instead of "return strlen(buffer)", just

return p - buffer;

which is a bit more efficient (strlen will scan all the way from start
to end to find the NUL).
 
B

Ben C

/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
[..]
Maybe a better (and working) version would be:

size_t remove_comments(char *buffer)
{
char *p;

if(strchr(buffer, '#') == NULL)
return strlen(buffer); /* no comment found */

for(p = buffer; *p != '\0' && *p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return strlen(buffer);
}

Well, or just do it like this:

size_t remove_comments(char *buffer)
{
char *p = strchr(buffer, '#');
if (p != NULL) *p = '\0';

return strlen(buffer);
}
 
S

stathis gotsis

Ben C said:
/**
* Remove comments denoted with a preceding '#' in a given string
*
* @param buffer Pointer to a string in which to remove comments from
* @return New length of string
*/
[..]
Maybe a better (and working) version would be:

size_t remove_comments(char *buffer)
{
char *p;

if(strchr(buffer, '#') == NULL)
return strlen(buffer); /* no comment found */

for(p = buffer; *p != '\0' && *p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return strlen(buffer);
}

Well, or just do it like this:

size_t remove_comments(char *buffer)
{
char *p = strchr(buffer, '#');
if (p != NULL) *p = '\0';

return strlen(buffer);
}

Thanks for the suggestion, i got stuck on correcting the initial code, and
as a result i made one more mistake and missed the obvious. Too bad.
 
R

Robert Latest

On Mon, 10 Apr 2006 20:57:06 +0300,
in Msg. said:
Maybe a better (and working) version would be:

size_t remove_comments(char *buffer)
{
char *p;

if(strchr(buffer, '#') == NULL)
return strlen(buffer); /* no comment found */

for(p = buffer; *p != '\0' && *p != '#'; p++) ;

/* at this point, *p should be either '#' or '\0' */
*p = '\0';

return strlen(buffer);
}

How about just:

strtok(buffer, "#");

robert
 
S

stathis gotsis

Robert Latest said:
On Mon, 10 Apr 2006 20:57:06 +0300,


How about just:

strtok(buffer, "#");

I tend to avoid strtok() in general, but it can work in simple cases like
this one.
 
W

WaterWalk

I. Myself 写é“:
This is about reading the .ini files which are used in several of our
projects.

Currently, the actual read of each line of the file is with this statement:

fscanf(file, "%s %s", name, value); /* reads two strings from .ini
file */

This works, but it does not allow any comments to the right of the two
strings.
I would like to allow the .ini file to have long comments on the right.
Even better would be to allow additional lines of commentary also. The
computer should ignore the commentary, and just read the initial two
strings on each line.

Can anyone tell me how to do it?

Thanks,

Mitchell Timin

--
I'm proud of http://ANNEvolve.sourceforge.net. If you want to write software,
or articles, or do testing or research for ANNEvolve, let me know.

Humans may know that my email address is: (but remove the 3 digit number)
zenguy at shaw666 dot ca

Those suggestions are all good in simple situations. But what if there
are comment indicator such as "#" inside the "Key=Value" pair? For
example: Val1="ab#3". Then to simply search the "#" symbol and discard
the right part won't work. So I intend to put comment in a separate
line. This makes things simple.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top