Parsing Data From Text File

All - I must be missing something. I am reading in a text file which consists of repeating three lines of unique data.

0 TITAN 34B DEB
1 23647U 81038C 19157.21662220 +.00000228 +00000-0 +14345-3 0 9998
2 23647 062.9385 232.5848 6824308 263.6292 021.1815 02.72092572002376

These are orbits for satellites and the file has a number of different satellites. I wrote some (awkward?) code to read these in and parse them - storing various parameters in a structure. Then I wanted to sort them by various parameters - inclination, etc. and found Qsort which saved me about a week of effort! Now I'd like to write a bit of code that recognizes that the satellite number (23647) has an "epoch time" of 19157.blah where there are many unique satellites in the file. So I would fopen a text file, put the various satellites into a structure, and when the epoch time updates - save a new orbit. I would get a new text file once a week or so.

There should be a library that does something like this? This seems like a common task but I have looked thru Reference and didn't see anything. I have parts of this working but probably someone much better at coding than I am has done this long ago??

PS This is NOT a homework assignment.
library to do which?
to read text files into a structure? Not really: there is no one-size fits all. C++ is strongly typed, so such a tool would either have to read it all as text (useless?) and store it as text for you, and then you would need to manually turn it back to the right type, wasting time. Better to directly read this. But the format isnt clear, one has a U, one has none, one has + and the other not, there is no consistency that I can see here.

qsort is C. std::sort is c++ version.
are you writing this in C?

jonnin Thanks for the reply. I started in C but have moved mostly to C++ and intend to write in C++ now, I should change my library from Qsort to std::sort! I am a Macintosh guy and use the Mac IDE called Xcode and the code that I have written complies in C and C++ so far.

I read text files easily now and parse them into a structure - I got some good help here when I was doing that. The files that I have to start with follow a format established back in about 1965 and I have no control over that but have written code that imports it w/o problems.

Now I am writing code to read in a text file and parse the parameters - but also to keep each unique updated orbit. So I would have a structure with satellite number 23647 and several entries - each with a unique "19157.2166" part. That is called the "epoch time" and is 2019 day 157.2166 so that is the field that tells me that the orbit has been updated. I would look at a new input file every week or so.

Is there a library to recognize that 23647 is the unique ID for an object and then to add a part of the structure if the epoch time has changed?

Is this sort of understandable??
Last edited on
CharlesPhillips wrote:
Now I'd like to write a bit of code that recognizes that the satellite number (23647) has an "epoch time" of 19157.blah where there are many unique satellites in the file.


Assuming your file looks like this:
0 TITAN 34B DEB
1 23647U 81038C 19157.21662220 +.00000228 +00000-0 +14345-3 0 9998


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;
    
struct Satellite
{
    int number;
    string name;
    double epoch_time;
};

int main()
{
    ifstream fin("file.txt");
    
    // ignore "header" information (first line)
    string ignore;
    getline(fin, ignore);
    
    vector<Satellite> sats;
    
    int number;
    string name;
    double epoch_time;
    
    while (fin >> number >> name >> ignore >> epoch_time >> ignore >> ignore >> ignore >> ignore >> ignore)
    {
        sats.push_back( Satellite { number, name, epoch_time } );
    }
    
    for (const auto& sat : sats)
    {
        cout << "Satellite " << sat.number << ": \n"
             << "  name: " << sat.name << '\n'
             << "  epoch time: " << sat.epoch_time << '\n';
    }
}


I didn't bother trying to parse your third line because, as jonnin said, it isn't consistent with the second line. The second line has 9 tokens, while the third line has 8 tokens.
Last edited on
CharlesPhillips wrote:
The files that I have to start with follow a format established back in about 1965 and I have no control over that but have written code that imports it w/o problems.

But what is the format? From our perspective, we have no idea what it means.
If you explained the file format, we could help you parse it.

Is there a library to recognize that 23647 is the unique ID for an object and then to add a part of the structure if the epoch time has changed?

If the format you're working with is some well-known format, there might be a library for it. Otherwise, no, it's just text; there's no way to know a priori that 23647 is a UID. You have to tell it that.

EDIT:
After a bit of research, I see that your data is called "Two-line element set"
https://www.n2yo.com/satellite/?s=44321
Two Line Element Set (TLE):
1 44321U 81038G   19246.26656351  .00000134  00000-0  14779-3 0  9999
2 44321  63.1812 223.6710 6374961 258.2475  28.4670  3.26864237  2715

Is that correct?

(Okay, I seem to be misunderstanding what you're trying to achieve, based on Duthomhas' post)
Last edited on
OP has repeatedly indicated that he is already parsing and storing the data. What he wants is to get a list of only those records with updated data, conveniently identifiable by the record's date field.

I recommend a simple sort functor (to use with std::sort) to put the records in order by ID number and date. Something like

1
2
3
4
5
6
bool sort_by_id_and_time( const satellite& a, const satellite& b )
{
  if (a.id < b.id) return true;
  if (b.id < a.id) return false;
  return a.time < b.time;
}

Adapt to your needs.

Oh, forgot to say, after that, just loop through the list of satellites, keeping track of which is the current ID, and if one has updated time. If you wish you can get fancy using the lower_bound() and upper_bound() functions in <algorithm>, but either way you will have to do some bookkeeping yourself to track the current satellite.

There aren't so many satellites in orbit that it should take very long.

Hope this helps. Eye
Last edited on
All - this is very helpful!

I am not an experienced programmer and had not seen the >> ignore >> but that looks handy. I wrote code to input/parse all parameters for all three lines - and put them into a structure. I think that the >> ignore could have saved me a lot of time :-(

I will have to look more at line 23 and see what the vector does. And what sats.push_back does, line 31.

I am gonna merge Ganado's code and my structure and see what happens on a real file. I will probably post back tomorrow.

The format for this orbital information is explained at Space-Track.org
vectors are a lot like arrays. But they also have stack data structure ideas. Push back literally treats the 'array' as if it were a 'stack' and pushes the next piece of data onto the 'back':
that is:
123
pushback(4)
becomes 1234
(conceptually, ignored syntax).

Ganado, et al -

EDIT:
After a bit of research, I see that your data is called "Two-line element set"
https://www.n2yo.com/satellite/?s=44321
Two Line Element Set (TLE):
1 44321U 81038G 19246.26656351 .00000134 00000-0 14779-3 0 9999
2 44321 63.1812 223.6710 6374961 258.2475 28.4670 3.26864237 2715

Is that correct?


This is the infamous Three Line Element Set (TLE) format which adds the satellite name as "card 0" while card 1 and 2 have the orbital elements. TLE is also used to refer to just the two cards and this is a bit confusing. This was first created for the ancient 496L computer system which did so much of the original work of tracking objects in space.

I am rewriting my code to read and parse the TLEs now, making it more compliant to C++ and putting in the pushback so far. This is all on Github if anyone wants to see the whole enchilada.
I have not forgotten - got distracted by a proposal to the National Science Foundation and a project analyzing some satellite's orbits. I am hoping to get back at it this weekend.
had not seen the >> ignore >> but that looks handy.

It is nothing special, just inserting a value into a variable that isn't later used.

Read a value from the file and discard it.
Topic archived. No new replies allowed.