Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Newbie - Reading and Parsing from Text File

Reply
Thread Tools

Newbie - Reading and Parsing from Text File

 
 
Mojo
Guest
Posts: n/a
 
      01-03-2008
Hi,

I am new to C programming, so bear with me..

There is a text file that have lines like:

00001 John Doe
00002 Ronnie Williams
....
....

Each columns have fixed lengths:

number --> 10 chars long
name ---> 15 chars long
lastname ---> 20 chars long

I cannot use something like " sscanf("%s %s %s"),no,name,lastname)
" because it fails if there one has a midlle name..

I'd appreciate if you help me with that..
Thank you..
 
Reply With Quote
 
 
 
 
Randy Howard
Guest
Posts: n/a
 
      01-03-2008
On Thu, 3 Jan 2008 08:48:34 -0600, Mojo wrote
(in article
<(E-Mail Removed)>):

> Hi,
>
> I am new to C programming, so bear with me..
>
> There is a text file that have lines like:
>
> 00001 John Doe
> 00002 Ronnie Williams
> ...
> ...
>
> Each columns have fixed lengths:
>
> number --> 10 chars long
> name ---> 15 chars long
> lastname ---> 20 chars long
>
> I cannot use something like " sscanf("%s %s %s"),no,name,lastname)
> " because it fails if there one has a midlle name..


If you know that each "field" is always contained completely within the
widths specified above, for example you never have a case like this:

> 00002 Ronnie Williams

02345 Esmereldamamasita Mylastnameisincrediblylongohmy


If that can't happen, then you can just read in the entire line, with
something like fgets(), or some of the alternatives such as fgetline()
or ggets() that some of the regulars have placed out there.

Once you have an intact line (presumably at least 45 chars long, plus a
newline or a \0), then just chop up the text into segments, one 10
chars long, one 15 chars long, and one 20 chars long.

If you want to trim off trailing spaces, you may do so afterward. If
tabs are used, you would have to know if tabs had a fixed tab width
expansion or not in order to deal with them properly.



--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw





 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      01-03-2008
Mojo wrote:
>
> I am new to C programming, so bear with me..
>
> There is a text file that have lines like:
>
> 00001 John Doe
> 00002 Ronnie Williams
> ...
> ...
>
> Each columns have fixed lengths:
>
> number --> 10 chars long
> name ---> 15 chars long
> lastname ---> 20 chars long
>
> I cannot use something like " sscanf("%s %s %s"),no,name,lastname)
> " because it fails if there one has a midlle name..


Don't use scanf. Use, for example, getc() and a counter.

--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.


--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Jim
Guest
Posts: n/a
 
      01-03-2008
On 2008-01-03, CBFalconer <(E-Mail Removed)> wrote:
> Mojo wrote:
>>
>> I am new to C programming, so bear with me..
>>
>> There is a text file that have lines like:
>>
>> 00001 John Doe
>> 00002 Ronnie Williams
>> ...
>> ...
>>
>> Each columns have fixed lengths:
>>
>> number --> 10 chars long
>> name ---> 15 chars long
>> lastname ---> 20 chars long
>>
>> I cannot use something like " sscanf("%s %s %s"),no,name,lastname)
>> " because it fails if there one has a midlle name..

>
> Don't use scanf. Use, for example, getc() and a counter.


I'd go with a struct that matches the table layout, then use fread()

Jim
--
http://www.ursaMinorBeta.co.uk

"The Sierpinski Gasket makes me want to cry."
- Jonathon Coulton, "Mandelbrot Set"
 
Reply With Quote
 
Mojo
Guest
Posts: n/a
 
      01-03-2008

> Once you have an intact line (presumably at least 45 chars long, plus a
> newline or a \0), then just chop up the text into segments, one 10
> chars long, one 15 chars long, and one 20 chars long. *


In fact, i have something like this to fetch the parts:

void strMid(char _source[100], int _where, int _width) { // similar
to Mid() in Basic
char _temp[100];
int _counter;

for(_counter=_where;_counter<=_where+_width;_count er++)
{
_temp[_counter- _where] = _source[_counter];

}
_temp[_width] = 0;

strcpy(_source,_temp);
}

I've tried but couldn't write a string returning version of this
function.

 
Reply With Quote
 
Mojo
Guest
Posts: n/a
 
      01-03-2008
Ok, I've figured what was going wrong..
I was having unhandled exception errors in VC++ and I thought there
was
something wrong with my code but I switched to Turbo C++ a few mins
ago and
everything is working good now.
Thanks for your replies anyway..

 
Reply With Quote
 
andreyvul
Guest
Posts: n/a
 
      01-03-2008
On Jan 3, 12:19 pm, Mojo <(E-Mail Removed)> wrote:
> > Once you have an intact line (presumably at least 45 chars long, plus a
> > newline or a \0), then just chop up the text into segments, one 10
> > chars long, one 15 chars long, and one 20 chars long.

>
> In fact, i have something like this to fetch the parts:
>
> void strMid(char _source[100], int _where, int _width) { // similar
> to Mid() in Basic
> char _temp[100];
> int _counter;
>
> for(_counter=_where;_counter<=_where+_width;_count er++)
> {
> _temp[_counter- _where] = _source[_counter];
>
> }
> _temp[_width] = 0;
>
> strcpy(_source,_temp);
>
> }
>
> I've tried but couldn't write a string returning version of this
> function.

Because char[] data is allocated on the stack, not on the heap.
Stack data: allocated when entering function, reclaimed when exiting
function.
Heap data: allocated with malloc/calloc/realloc, reclaimed with free/
realloc.

In other words, char[] is an alloca() array.
Corrected strMid:
char* strMid(char *_source, unsigned _where, unsigned _width) {
char *temp = calloc(_width + 1, 1); /* malloc + memset(temp, 0,
_width + 1) */
strncpy(temp, _source + _where, _width);
return temp;
}

Note: to prevent memory leaks, call the function like this:
void foo(void) {
char bar[50];
char *baz = strMid(bar, 5, 5);
/* do something with baz */
...
free(baz);
baz = strMid(bar, 10, 7);
/* do something with baz */
...
free(baz);
/* etc */
}

 
Reply With Quote
 
jameskuyper@verizon.net
Guest
Posts: n/a
 
      01-03-2008
Mojo wrote:
> Ok, I've figured what was going wrong..
> I was having unhandled exception errors in VC++ and I thought there
> was
> something wrong with my code but I switched to Turbo C++ a few mins
> ago and
> everything is working good now.
> Thanks for your replies anyway..


You were using C++, and you posted your question to comp.lang.c
indicating that it was a question about C. Why?
 
Reply With Quote
 
Mojo
Guest
Posts: n/a
 
      01-03-2008

> You were using C++, and you posted your question to comp.lang.c
> indicating that it was a question about C. Why?


I am not coding in C++, just using VC++ and Turbo C++ to compile..
 
Reply With Quote
 
Mojo
Guest
Posts: n/a
 
      01-03-2008
On 3 Ocak, 21:16, andreyvul <(E-Mail Removed)> wrote:
> On Jan 3, 12:19 pm, Mojo <(E-Mail Removed)> wrote:
>
>
>
> > > Once you have an intact line (presumably at least 45 chars long, plus a
> > > newline or a \0), then just chop up the text into segments, one 10
> > > chars long, one 15 chars long, and one 20 chars long.

>
> > In fact, i have something like this to fetch the parts:

>
> > void strMid(char _source[100], int _where, int _width) { *// similar
> > to Mid() in Basic
> > * * * * char _temp[100];
> > * * * * int _counter;

>
> > * * * * for(_counter=_where;_counter<=_where+_width;_count er++)
> > * * * * {
> > * * * * * * * * _temp[_counter- _where] = _source[_counter];

>
> > * * * * }
> > * * * * _temp[_width] = 0;

>
> > * * * * strcpy(_source,_temp);

>
> > }

>
> > I've tried but couldn't write a string returning version of this
> > function.

>
> Because char[] data is allocated on the stack, not on the heap.
> Stack data: allocated when entering function, reclaimed when exiting
> function.
> Heap data: allocated with malloc/calloc/realloc, reclaimed with free/
> realloc.
>
> In other words, char[] is an alloca() array.
> Corrected strMid:
> char* strMid(char *_source, unsigned _where, unsigned _width) {
> * * char *temp = calloc(_width + 1, 1); /* malloc + memset(temp, 0,
> _width + 1) */
> * * strncpy(temp, _source + _where, _width);
> * * return temp;
>
> }
>
> Note: to prevent memory leaks, call the function like this:
> void foo(void) {
> * * char bar[50];
> * * char *baz = strMid(bar, 5, 5);
> * * /* do something with baz */
> * * ...
> * * free(baz);
> * * baz = strMid(bar, 10, 7);
> * * /* do something with baz */
> * * ...
> * * free(baz);
> * * /* etc */
>



Thanks a lot Andrey..
 
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
In file parsing, taking the first few characters of a text file after a readfile or streamreader file read... .Net Sports ASP .Net 11 01-17-2006 12:44 AM
reading and parsing fixed length text file Julian McMaster Java 1 11-08-2005 02:45 AM
reading the DB vs. reading a text file...performance preference? Darrel ASP .Net 3 11-11-2004 02:27 PM
Assistance parsing text file using Text::CSV_XS Domenico Discepola Perl Misc 6 09-02-2004 03:55 PM
reading and writing to text file via form newbie Trotsky Perl Misc 6 11-24-2003 08:57 PM



Advertisments