Solved

Read line in file

Posted on 2006-07-02
21
232 Views
Last Modified: 2012-05-05
I am using fread to read in a tab-delimited line from a text file with a set # of items.

I put together a struct (record) to represent the # of items in each line.  Rather than using strtok, I would prefer reading the line directly into a struct.  I'd appreciate any examples.

Thank you.
0
Comment
Question by:jewee
  • 7
  • 5
  • 3
  • +2
21 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
If you can provide the struct you want to put it into as well as an explanation how the fields corellate, that should not be a problem. Without that, that is plain guessing.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Actually, ignore my last comment. Given the feedback and lack of cooperation you gave in your last Qs - especially the last one, where I put in a *lot* of effort - I am not going to help you fixing your problems any longer, especially since you come back to your Qs a week later erliest. Have fun!
0
 
LVL 15

Expert Comment

by:bpmurray
Comment Utility
If you have a tab-delimited text file, you can't read directly into a struct unless some very strict criteria are met. Are the fields in each position the same size in each line? Do the lines have a fixed length? Are the TAB characters in the same position in each line? Are the values all text values, or are the numeric values in binary?
0
 

Author Comment

by:jewee
Comment Utility
jkr, what do you mean by my lack of cooperation?  Which question are you referring to?   I apologize for not grading the solutions in a more timely manner.  I appreciate your feedback and solutions with some of the problems I've been having.  My work changes quite frequently which leads me to post random questions.

Jkr, I will make it a point to grade and award points sooner.  Your feedback has helped me through some tight deadlines I have been trying to reach.  I am not a software person (more ee than software).   I make it a point to set the number of points for each question I have to the max and always give high ratings.

Jkr, is there anything I can do to rectify the situation?

In the meantime, in regards to the question I asked here.  I currently have it implemented where I use strtok to retrieve each item.  The struct consists of 5 strings and 7 ints.  Each line within the file must follow this format.  I was just wondering if there was a simpler way to implement this reading directly into a struct.  If so, I was just basically looking for a general example.  If not, I will just keep it the way it is.  The lines have a fixed length and the tab characters are in the same position.

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
jewee, I was referring to you 'Parse filename' Q. I wrote that that could be done by a simple search and replace operation, yet I coded a full 'splitpath()' path parsing replacement (there's a 'TCL_splitpath()' on Linux, but that was out of question) where you have access to each path element to change and you did not say a word for a whole week.. You accepted the 'search and replace' answer (which for sure works, that's why I mentioned it) without any further comment. Since writing a 'splitpath()' is neithr rocket science nor trivial yet costs some time and you get absolutely no feedback, that's disappointing.

>>is there anything I can do to rectify the situation?

In general, be responsive. Get back to your Qs in time and don't leave them open for such a long time. Remember: All the people here are real people (with all their weaknesses) and - what's more important - volunteers that post on EE in their spare time. So treating them as people (and that includes responsiveness) is the best  thing you can do.

>>In the meantime, in regards to the question I asked here.  I currently have it implemented where I
>>use strtok to retrieve each item.  The struct consists of 5 strings and 7 ints.

Then you'll have to contine splitting up the fields, since you cannot directly read them to struct elements using 'fread()'. Yet you could use C++ file streams to read them, which atill requires some workarounds, e.g.

struct foo {

char field1 [ 255];
char field2 [ 255];

int n1;
int n2;

};

void replace_delimiter(string& s) {

int nPos = 0;

while( -1 != (nPos = s.find('#',nPos))) { s[nPos] = ' '; ++nPos;}

}

void read_struct_foo(ifstream& is, foo& f) {

string strLine;

getline(is,strLine);
replace_delimiter(strLine);

is >> f.field1;
is >> f.field2;

is >> f.n1;
is >> f.n2;

}

//...

ifstream is("file.txt);
foo f;

read_struct_foo(is,f);
0
 
LVL 15

Accepted Solution

by:
bpmurray earned 168 total points
Comment Utility
To read it into a struct, you could do something like what's below. However, it wouldn't really get you a whole lot since all the numbers would be in a string, and all strings would not be NULL-terminated. I think your strtok solution is probably the best.

typedef struct {
     char  str1[10];        /* First strig */
     char  tab1;              /* for tab character */
     char  str2[6];          /* Second string */
     char tab2;              /* Next tab */
     char num1[4];        / Numeric value */
     char tab3;              /* next tab */
     etc.
} RECSTRUCT;

RECSTRUCT myRec;

fgets((char *) myRec, sizeof(RECSTRUCT), fp);
tab1 = tab2 = tab3 = ..... = tabn = 0;

0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 166 total points
Comment Utility
Correction on my side

void read_struct_foo(ifstream& is, foo& f) {

string strLine;

getline(is,strLine);
replace_delimiter(strLine);

stringstream ss;

ss << strLine;

ss >> f.field1;
ss >> f.field2;

ss >> f.n1;
ss >> f.n2;

}

and you'll need to

#include <fstream>
#include <sstream>
#include <string>
using namespace std;


>>fgets((char *) myRec, sizeof(RECSTRUCT), fp);

But that won't work if the ints have a textual representation.
0
 
LVL 15

Expert Comment

by:bpmurray
Comment Utility
>>fgets((char *) myRec, sizeof(RECSTRUCT), fp);

>But that won't work if the ints have a textual representation.

Actually, it will - I tested it. However, read my comments: since the numbers are in text format, using strtok is probably the simplest solution.

      
      
0
 

Author Comment

by:jewee
Comment Utility
I just checked that question - that was a mistake!  I didn't use that solution!  I needed to parse the whole filename.  I am so sorry for that!  I was closing out that question later on - rather quickly.  That was a misunderstanding.  I should have closed out that question when I looked at your solution.  I was distracted at work when going through that.

I am really sorry about that.  I will contact the moderator.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 86

Expert Comment

by:jkr
Comment Utility
Wait a minute, if itsmeandnobodyelse's solution works for you, there's not need to assing the whole Q to me.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Let me be more precise: If that works for you, I'd also have been happy with a "I have chosen that solution beause it was the easiest for me and thanks all".
0
 

Author Comment

by:jewee
Comment Utility
I already knew about the find and replace.  Seriously - it was a mistake - take the points!
Thank you again.
0
 
LVL 5

Expert Comment

by:bastibartel
Comment Utility
Funny - It appears as if this thread is taking the course of so many in public forums... What was the question again ;-)
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
>>>> Funny - It appears as if this thread is taking the course of so many in public forums...

Indeed, it's interesting ...


>>>> What would be the simplest way of parsing a filename with path and renaming it?

jewee, the above was your question in the last thread. Do you think it is believable if you now say "I already knew about the find and replace".

Note, you absolutely have the right to accept jkr's solution even though it isn't "the simplest" solution you had asked for. You also have the right to change your mind if you made a mistake. But the least I could have expected is some feedback and an explanation.

Instead you took me for a fool ...

Regards, Alex


0
 

Author Comment

by:jewee
Comment Utility
Alex,

Sorry - meant to provide you with an explanation.  This has been tiresome and I am trying to allocate points to the correct person.  If mistakes happen, then - yes = an explanation of the mistake is necessary.

In detail, this is my explanation:

  I need to parse through the filename in order to modify/create new directory structures based on naming conventions specified.  Then, from there - I needed to include functionality to take a file - and have the flexibility to move it to another directory in an entirely new directory structure or the file needs to be moved to levels above the current directory which would entail having to parse the whole filename path in order to have that level of flexibility.

When I closed out the question - I looked at it too quickly not realizing what I have used from that question.  At the time, I reached 5 questions - didn't have the time to close them out - so I chose one question - closed it out - oops - wrong one.  I didn't realize it until jkr brought it to my attention.

To rectify the situation  - this is what I am doing -
    Not letting questions sit for long - awarding points ASAP.
   Taking the time to determine who deserves a certain number of points.

Your feedback was helpful...now in the future, of course, I plan on posting more questions - I ALWAYS RATE THEM AT 500 POINTS.  I apologize for the inconvenience.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
jewee,

You're almost getting into a feedback frenzy now (compared to earlier times), I can just hope you are gonna keep up part of that in your future Qs also ;o)

Communication is the key.
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 166 total points
Comment Utility
>>>> The lines have a fixed length and the tab characters are in the same position

That is strange for a text file. Do you pad the char fields with spaces? Does 'same position' mean 'same byte position' ?

if so, bpmurrays solution is great though I would go from C to C++:

#include <sys/stat.h"
#include <vector>
#include <fstream>
using namespace std;

struct Record
{
     char  str1[10];        /* First strig */
     char  tab1;              /* for tab character */
     char  str2[6];          /* Second string */
     char tab2;              /* Next tab */
     char num1[4];        / Numeric value */
     char tab3;              /* next tab */
     // and so one
     istream& operator>> (istream& is, Record& rec)
     {
           is.read((char*) rec, sizeof(Record));
           char crlf[2];  
           if (is)
              is.read(crlf, 2);
           return is;
     }
};

   Record rec;

   struct stat status;
   if (stat("test.dat", &status) != 0)
       return;
   ifstream ifs("test.dat", ios::in | ios::binary);
   Record rec;
   vector<Record> recs;
   while (ifs >> rec)
       recs.push_back(rec);

   ifs.close();

Regards, Alex

0
 

Author Comment

by:jewee
Comment Utility
I am finding this difficult to grade.  I'll have to think about this one.  I can take ideas from each of the solutions.  I prefer the vector of records approach.  However, other solutions are also helpful.  

Okay, I will do my best to grade this fairly and analyze each solution carefully.  If someone is not happy with my decision - please, let me know!  I will be more careful in grading these in the future.  Jkr, like what you said, communication is key.

Thank you!
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now