Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > fgets

Reply
Thread Tools

fgets

 
 
Magix
Guest
Posts: n/a
 
      08-27-2004
Hi,

I'm not too sure on reading specify string with the first < > from file
stream,and make the file pointer go to next line, with fgets. or any better
idea.

E.g
let say text.txt has
<11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
<22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
<333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>

while(fgets(num, 7, fp)!=NULL)
{
// filter the < and >
printf( "%s",num );
// go to new line
}

it will print num:
11111
22222
33333

Advise...pls. Thanks

Regards.


 
Reply With Quote
 
 
 
 
Magix
Guest
Posts: n/a
 
      08-27-2004

"Magix" <(E-Mail Removed)> wrote in message
news:412ed35b$(E-Mail Removed)...
> Hi,
>
> I'm not too sure on reading specify string with the first < > from file
> stream,and make the file pointer go to next line, with fgets. or any

better
> idea.
>
> E.g
> let say text.txt has
> <11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
> <22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
> <333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>
>
> while(fgets(num, 7, fp)!=NULL)
> {
> // filter the < and >
> printf( "%s",num );
> // go to new line
> }
>
> it will print num:
> 11111
> 22222
> 33333
>
> Advise...pls. Thanks
>
> Regards.
>
>


Sorry, it will print num:
11111
22222222
333


 
Reply With Quote
 
 
 
 
Mike Wahler
Guest
Posts: n/a
 
      08-27-2004

"Magix" <(E-Mail Removed)> wrote in message
news:412ed3cd$(E-Mail Removed)...
>
> "Magix" <(E-Mail Removed)> wrote in message
> news:412ed35b$(E-Mail Removed)...
> > Hi,
> >
> > I'm not too sure on reading specify string with the first < > from file
> > stream,and make the file pointer go to next line, with fgets. or any

> better
> > idea.
> >
> > E.g
> > let say text.txt has
> > <11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
> > <22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
> > <333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>
> >
> > while(fgets(num, 7, fp)!=NULL)


Why 7?

> > {
> > // filter the < and >
> > printf( "%s",num );
> > // go to new line
> > }
> >
> > it will print num:
> > 11111
> > 22222
> > 33333
> >
> > Advise...pls. Thanks
> >
> > Regards.
> >
> >

>
> Sorry, it will print num:
> 11111
> 22222222
> 333



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LINE_SIZE 100 /* adjust to your needs */
#define LDELIM '<'
#define RDELIM '>'

int main()
{
FILE *fp = fopen("test.txt", "r");
static char line[LINE_SIZE];

if(!fp)
{
fprintf(stderr, "Cannot open input\n");
return EXIT_FAILURE;
}

while(fgets(line, sizeof line, fp))
{
char *left = 0;
char *right = 0;

if(left = strchr(line, LDELIM))
right = strchr(++left, RDELIM);

if(left && right)
{
*right = 0;
printf("%s\n", left);
}
}

if(!feof(fp))
{
fprintf(stderr, "Error reading input\n";
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

Input:

<11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
<22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
<333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>


Output:

11111
22222222
333

The above will only work correctly if all lines are less than
;LINE_SIZE; characters. If they're larger and you don't increase
'LINE_SIZE' to accomodate, you'll need to handle cases where
a single 'fgets()' call doesn't extract a newline character.

-Mike

>
>



 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      08-27-2004
Hi Magix,

>>I'm not too sure on reading specify string with the first < > from file
>>stream,and make the file pointer go to next line, with fgets. or any

>
> better
>
>>idea.
>>
>>E.g
>>let say text.txt has
>><11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
>><22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb >
>><333><Jim><ccccccccccccccccccccccccccccccccccccc cccccc>
>>
>>while(fgets(num, 7, fp)!=NULL)
>>{
>> // filter the < and >
>> printf( "%s",num );
>> // go to new line
>>}
>>

>
> It will print num:
> 11111
> 22222222
> 333


You can also use fscanf():

#include <stdio.h>
#include <stdlib.h>

#define STRINGIZE(s) # s
#define MAKESTRING(s) STRINGIZE(s)

#define FIELDWIDTH 7

int main (void)
{
FILE *fp;
char str[FIELDWIDTH+1];

if ( (fp=fopen("magix.inp","r")) == NULL )
exit(EXIT_FAILURE);

while (1) {
int howmany = fscanf(fp, "<%"MAKESTRING(FIELDWIDTH)
"[^>]%*[^<]<%*[^>]><%*[^>]>",
str);
if (howmany!=1)
break;
puts(str);
}
fclose(fp);

exit(EXIT_SUCCESS);
}

The format string does the following:
It gobbles a '<', then scans for up to FIELDWIDTH non-'>'
characters into str. As we do not know whether this covers
the first "<tag>", we now scan for the beginning of
the second, then gobble the second and third tags, respectively.
The leading ' ' is for gobbling any left over white spaces
from previous line.

Note, however, that this does not give you the certainty that
your line was of the required format. You could scan for the
final '>' or try to fgetc() the following '\n' to be on the
safe side.

It might be a good idea to #define left/right delimiter
characters instead of '<','>'. You can insert them quite
in the same way as the FIELDWIDTH.


Cheers,
Michael

 
Reply With Quote
 
William L. Bahn
Guest
Posts: n/a
 
      08-27-2004

"Michael Mair" <(E-Mail Removed)-stuttgart.de>
wrote in message
news:cgn1fl$7hk$(E-Mail Removed)-stuttgart.de...
> Hi Magix,
>
> >>I'm not too sure on reading specify string with the first < >

from file
> >>stream,and make the file pointer go to next line, with fgets.

or any
> >
> > better
> >
> >>idea.
> >>
> >>E.g
> >>let say text.txt has
> >><11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
> >><22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb >
> >><333><Jim><ccccccccccccccccccccccccccccccccccccc cccccc>
> >>
> >>while(fgets(num, 7, fp)!=NULL)
> >>{
> >> // filter the < and >
> >> printf( "%s",num );
> >> // go to new line
> >>}
> >>

> >
> > It will print num:
> > 11111
> > 22222222
> > 333

>
> You can also use fscanf():
>
> while (1) {
> int howmany = fscanf(fp, "<%"MAKESTRING(FIELDWIDTH)
> "[^>]%*[^<]<%*[^>]><%*[^>]>",
> str);
>
> The format string does the following:
> It gobbles a '<', then scans for up to FIELDWIDTH non-'>'
> characters into str. As we do not know whether this covers
> the first "<tag>", we now scan for the beginning of
> the second, then gobble the second and third tags,

respectively.
> The leading ' ' is for gobbling any left over white spaces
> from previous line.
>
> Note, however, that this does not give you the certainty that
> your line was of the required format. You could scan for the
> final '>' or try to fgetc() the following '\n' to be on the
> safe side.
>
> It might be a good idea to #define left/right delimiter
> characters instead of '<','>'. You can insert them quite
> in the same way as the FIELDWIDTH.
>


Why so complicated?

What happens if there is a space in the input string?
What happens if there aren't exactly three pairs of tags on a
line (which I don't see any requirement for - the example just
happens to have three on each line)?

For what the OP is asking for, if I understand it correctly, you
don't need to perform string operations at all.

This is the way I read what is being asked for (which,
admittedly, involved reading between the lines):

1) Lines consist of strings of characters delimited by '<'
(LDELIM) and '>' (RDELIM) characters.
2) There may be one or more such strings on a given line.
3) Output should consist only of the first such string on each
line.

IF we are willing to assume (for the first pass at the algorithm)
that the strings really do obey Rule #1, then we have the
following:

1) WHILE: End of File not reached
1.1) WHILE: (Next character is NOT LDELIM)
1.1.1) Do nothing - go on to next character.
1.2) WHILE: (Next character is NOT RDELIM)
1.2.1) Print the character.
1.3) Print a newline character.
1.4) WHILE: (Next character is NOT the end of the line)
1.4.1) Do nothing - go on to the next character.

Each of the tests should include checks for EOF and (if desired)
newline characters in unexpected places.

At the risk of doing someone's homework (hopefully they'll at
least learn something from seeing the problem stated clearly, an
algorithm developed based on the problem statement, and code
developed based on the algorithm).

#include <stdio.h> /* FILE, NULL, fopen(), putchar(), printf()
*/

#define EXIT_OK (0)
#define EXIT_FAIL_NoOpen (1)

#define FILENAME "data.txt"

#define LDELIM ('<')
#define RDELIM ('>')

int main(void)
{
int c;
FILE *fp;

fp = fopen(FILENAME, "rt");
if(NULL == fp)
{
printf("Error opening %s for reading - aborting.\n",
FILENAME);
return EXIT_FAIL_NoOpen;
}

do /* Until end of file is reached */
{
/* Strip up to and including first occurrence of LDELIM
*/
while( (EOF != (c = getc(fp))) && ('\n' != c) &&
(LDELIM != c) )
/* EMPTY LOOP */;

/* Print out characters up to first occurrence of
RDELIM */
while( (EOF != (c = getc(fp))) && ('\n' != c) &&
(RDELIM != c) )
putchar(c);
putchar('\n');

/* Strip remaining characters on line */
while( (EOF != (c = getc(fp))) && ('\n' != c) )
/* EMPTY LOOP */;

} while (EOF != c);

fclose(fp);

return EXIT_OK;
}


As usual, I welcome comments and criticisms.

NOTE TO THE OP: By using the subject line you did, you imply that
your question is specifically dealing with a specific function -
namely fgets() - and people might assume that, for whatever
reason, you either have to use that function or are trying to
learn more about that function by doing so. Your post content
implies that this is not the case. A better subject line might
have been something like: "Trying to output initial part of each
line".




 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      08-27-2004
"Magix" <(E-Mail Removed)> wrote in message news:<412ed3cd$(E-Mail Removed)>...
> "Magix" <(E-Mail Removed)> wrote in message
> news:412ed35b$(E-Mail Removed)...


> > I'm not too sure on reading specify string with the first < > from file
> > stream,and make the file pointer go to next line, with fgets. or any
> > better idea.


I'm afraid I don't understand you. Do you mean "I want to read the
text
enclosed by <>, and then skip to the next line"?

> > E.g
> > let say text.txt has
> > <11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
> > <22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
> > <333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>
> >
> > while(fgets(num, 7, fp)!=NULL)
> > {
> > // filter the < and >
> > printf( "%s",num );
> > // go to new line
> > }
> >
> > it will print num:
> > 11111
> > 22222
> > 33333

>
> Sorry, it will print num:
> 11111
> 22222222
> 333


no it won't. Do you mean that's what you want it to do? If so you
could get a character at a time.


--
Nick Keighley

My god it's full of stars!
Dave Bowman, on seeing HAL's source code
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      08-27-2004
Hello William,


> Why so complicated?
>
> What happens if there is a space in the input string?

(Then scan for white spaces which are not return between > and
<... but that is beside the point, see below)

> What happens if there aren't exactly three pairs of tags on a
> line (which I don't see any requirement for - the example just
> happens to have three on each line)?
>
> For what the OP is asking for, if I understand it correctly, you
> don't need to perform string operations at all.


That may be the problem -- I did not entirely understand his
intention, so I made up one that seemed to fit... :-/
It seemed to me that he defined an input format which I
put into a format string as I do not think that fgets()
is the best thing to use. OTOH, he seemed to want to do
it "in one go", so I tried to give him that.


> This is the way I read what is being asked for (which,
> admittedly, involved reading between the lines):
>
> 1) Lines consist of strings of characters delimited by '<'
> (LDELIM) and '>' (RDELIM) characters.
> 2) There may be one or more such strings on a given line.
> 3) Output should consist only of the first such string on each
> line.


Er, right. Then the way is clear. My assumptions from his
input file were that
1,2) Lines consist of exactly three strings delimited by < and >
with no spaces between > and <, and a '\n' in the end.
3) Output should consist only of the first FIELDWIDTH (7 for the
OP) characters of the first string (or less, if the string has
strlen(string)<FIELDWIDTH) on each line.


Cheers
Michael

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      08-27-2004
Nick Keighley wrote:
> "Magix" <(E-Mail Removed)> wrote in message
>> "Magix" <(E-Mail Removed)> wrote in message

>
>>> I'm not too sure on reading specify string with the first < >
>>> from file stream,and make the file pointer go to next line,
>>> with fgets. or any better idea.

>
> I'm afraid I don't understand you. Do you mean "I want to read
> the text enclosed by <>, and then skip to the next line"?
>
>>> E.g
>>> let say text.txt has
>>> <11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
>>> <22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
>>> <333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>


If we say 'the initial text so delimited' then things should be
very simple:

Input the whole string, search for the first '<' and save the
pointer. Then search for the next '>' and zero that. Print the
string denoted by the saved pointer. Roughly:

if (firstp = strchr(buffer, '<')) firstp++;
if (firstp && (endp = strchr(firstp, '>')))
*endp = '\0';
puts(firstp);
else {
/* something isn't there */
}


--
"The most amazing achievement of the computer software industry
is its continuing cancellation of the steady and staggering
gains made by the computer hardware industry..." - Petroski


 
Reply With Quote
 
Malcolm
Guest
Posts: n/a
 
      08-27-2004

"Magix" <(E-Mail Removed)> wrote
>
> I'm not too sure on reading specify string with the first < > from file
> stream,and make the file pointer go to next line, with fgets. or any

better
> idea.
>
> E.g
> let say text.txt has
> <11111><Joe><aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>
> <22222222><Ron><bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>
> <333><Jim><ccccccccccccccccccccccccccccccccccccccc cccc>
>
> while(fgets(num, 7, fp)!=NULL)
> {
> // filter the < and >
> printf( "%s",num );
> // go to new line
> }
>
>

fgets() is useful if you can specify a maximum line length, and reject every
input over that limit (say 1024 characters). If you need to be able to
handle lines of any length, or if the input doesn't naturally fall into
lines, then it is not really useful and you need to write your own function
to read data into dynamically allocated memory.

You can parse simple input, like a block of text containing a few tag
delimited by <> just using a commonsense approach.

Once things get more complicated, for instance you allow nested tags, escape
sequences, and different types of tag, then you need to move to a recursive
parser. It is not easy to explain how to write one in a short post, but
basically you need a parsetag() function which calls itself when it hits a
nested tag. It also needs a match() function to flag an error if the closing
'>' is not detected at the appropriate place.




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[URGENT] fgets reading last line in file twice DJP C++ 7 10-21-2004 09:23 AM
fgets and newline Mike Mimic C++ 4 05-15-2004 06:19 AM
cin before fgets Charles Wilkins C++ 4 08-07-2003 10:14 PM
fgets and problems reading into array Eigenvector C Programming 12 07-29-2003 02:20 AM
Problems with fgets and reading in a number FakeAddress@NoSpam.com C Programming 6 06-25-2003 09:18 PM



Advertisments