Read line in file

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.
jeweeAsked:
Who is Participating?
 
bpmurrayConnect With a Mentor Commented:
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
 
jkrCommented:
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
 
jkrCommented:
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
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
bpmurrayCommented:
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
 
jeweeAuthor Commented:
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
 
jkrCommented:
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
 
jkrConnect With a Mentor Commented:
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
 
bpmurrayCommented:
>>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
 
jeweeAuthor Commented:
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
 
jkrCommented:
Wait a minute, if itsmeandnobodyelse's solution works for you, there's not need to assing the whole Q to me.
0
 
jkrCommented:
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
 
jeweeAuthor Commented:
I already knew about the find and replace.  Seriously - it was a mistake - take the points!
Thank you again.
0
 
bastibartelCommented:
Funny - It appears as if this thread is taking the course of so many in public forums... What was the question again ;-)
0
 
itsmeandnobodyelseCommented:
>>>> 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
 
jeweeAuthor Commented:
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
 
jkrCommented:
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
 
itsmeandnobodyelseConnect With a Mentor Commented:
>>>> 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
 
jeweeAuthor Commented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.