By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,079 Members | 1,788 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,079 IT Pros & Developers. It's quick & easy.

How to read strings from a file with comments

P: n/a
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
Apr 9 '06 #1
Share this Question
Share on Google+
15 Replies


P: n/a
I. Myself wrote:
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.

--
Ian Collins.
Apr 9 '06 #2

P: n/a
On Sun, 09 Apr 2006 21:04:40 GMT, in comp.lang.c , "I. Myself"
<No*****@Spam.none> wrote:
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
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Apr 9 '06 #3

P: n/a
"I. Myself" wrote:

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/>
Apr 9 '06 #4

P: n/a
I. Myself wrote:
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
Apr 9 '06 #5

P: n/a
Ian Collins <ia******@hotmail.com> writes:
[...]
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Apr 10 '06 #6

P: n/a
Keith Thompson wrote:
Ian Collins <ia******@hotmail.com> writes:
[...]
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.

Well spotted.

--
Ian Collins.
Apr 10 '06 #7

P: n/a

Ο/Η Joe Estock *γραψε:
I. Myself wrote:
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));
}


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.

Apr 10 '06 #8

P: n/a
On Sun, 09 Apr 2006 23:25:10 GMT, Joe Estock wrote:
/**
* 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

Apr 10 '06 #9

P: n/a
<st***********@hotmail.com> wrote in message
news:11**********************@g10g2000cwb.googlegr oups.com...

/ Joe Estock :
I. Myself wrote:
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));
}


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);
}
Apr 10 '06 #10

P: n/a
On 2006-04-10, stathis gotsis <st***********@hotmail.com> wrote:
<st***********@hotmail.com> wrote in message
news:11**********************@g10g2000cwb.googlegr oups.com...
/**
* 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).
Apr 10 '06 #11

P: n/a
On 2006-04-10, stathis gotsis <st***********@hotmail.com> wrote:
<st***********@hotmail.com> wrote in message
news:11**********************@g10g2000cwb.googlegr oups.com...
/**
* 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);
}
Apr 10 '06 #12

P: n/a
"Ben C" <sp******@spam.eggs> wrote in message
news:sl*********************@bowser.marioworld...
On 2006-04-10, stathis gotsis <st***********@hotmail.com> wrote:
<st***********@hotmail.com> wrote in message
news:11**********************@g10g2000cwb.googlegr oups.com...
/**
* 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.
Apr 10 '06 #13

P: n/a
On Mon, 10 Apr 2006 20:57:06 +0300,
stathis gotsis <st***********@hotmail.com> wrote
in Msg. <e1***********@ulysses.noc.ntua.gr>
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
Apr 11 '06 #14

P: n/a
"Robert Latest" <bo*******@yahoo.com> wrote in message
news:4a************@individual.net...
On Mon, 10 Apr 2006 20:57:06 +0300,
stathis gotsis <st***********@hotmail.com> wrote
in Msg. <e1***********@ulysses.noc.ntua.gr>
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, "#");


I tend to avoid strtok() in general, but it can work in simple cases like
this one.
Apr 11 '06 #15

P: n/a

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.

Apr 12 '06 #16

This discussion thread is closed

Replies have been disabled for this discussion.