LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to Read data from a Text file in this case ( C++ Programming) (https://www.linuxquestions.org/questions/programming-9/how-to-read-data-from-a-text-file-in-this-case-c-programming-693285/)

smasher 12-27-2008 11:35 AM

How to Read data from a Text file in this case ( C++ Programming)
 
Hi everyone,

I've been trying to read data from a text file and do some stuff with it.


text file :
------------------------------------------------------
2 // reads first line as number of tournaments
Tournament 1 // reads first tournament name
4 // reads number of teams participated
team1 // reads teams names
team2
team3
team4
6 // reads number of matches
team1#1@0#team2 // reads the scores
team1#1@1#team3
team1#2@1#team4
team2#3@0#team3
team2#2@2#team4
team3#1@2#team4
Tournament 2 // then do the same here
3
team a
team b
team c
3
team a#1@2#team b
team b#2@4#team c
team a#1@0#team c
-------------------------------------------------
Output file should be like this:
--------------------------------------------------
Tournament 1
a) team name [1], [2] ([3], [4], [5]), [6]gd ([7], [8])
rank) team name points, gamesPlayed (wins,ties,loses), goaldiff (goalScored, goalAgainst)
.
.
.
Tournament 2
.
.
.
----------------------------------------------------

where :
a= team rank
[1]= points earned
[2]= number of games played
[3]= number of wins
[4]= number of ties
[5]= number of loses
[6]= goal difference
[7]= goals scored
[8]= goals against

am stuck with the reading part ... any help would be appreciated


thnx,

agemo 12-27-2008 12:34 PM

Try using fscanf
 
Hello
My suggestion is to use fscanf because it allows you to read formated data. Also, writing formated data with fprintf is very easy.
Here's an example for what you wished
Code:

fscanf("%d\n", &nrOfTourns);
for (trn = 1; trn <= nrOfTourns; ++trn) {
  fscanf("%d\n", &nrOfTeams);
  for (team = 1; team <= nrOfTeams; ++team)
      fscanf("%s\n", teamName[team]); //teamName is char teamName[16][128]
  fscanf("%d\n", &nrOfMatches);
  for (match = 1; match <= nrOfMatches; ++match)
      fscanf("%s#%d@%d#%s", firstTeam, &score1, secondTeam, &score2);
}

The last fscanf accepts strings such as "Chelsea#2@1#ManchesterUtd" :P (it's just an example no offence to ManchesterUtd fans). Here, firstTeam will be "Chelsea", score1 = 2, secondTeam = "ManchesterUtd", score2 = 1

Tring to do this with streams (fstream, cin, cout) is way more tedious, and also slower.

smasher 12-27-2008 01:14 PM

well, tbh i am not used to program using that method ( still using fstream cin and cout method!)
i know its not efficient and way slower but am learning it atm

could you please re-write it using that method so i can clearly understand what you wrote
lets assume our input and output files are "input.txt", "output.txt"


btw, am also a BIG fan of Chelsea :D

jiml8 12-28-2008 08:25 AM

fscanf is not the C++ way and the prof probably won't give high marks for using it.

If you want help with homework you need to start by showing the work you have done and asking specific questions about what is wrong with it.

smasher 12-28-2008 12:57 PM

well.. am stuck with this part which is how to get the data from ( team1#1@0#team2 ) where i have to extract 2 team names and 2 results
i tried to make some for loops to get the data but still can't get the result and save it into its team record

so it would be like this:
goalScored[1]+=result1; //adds 1 to goalScored for team1
goalScored[2]+=result2; //adds 0 to goalScored for team2

i couldn't make the loop to extract em
sorry i can't post my code .. because our college has program that scans our codes and checks through the net if its got plagairisd or not

any ideas ...

agemo 12-28-2008 03:26 PM

hello again!
oh.. so it's C++ only, ok it still shouldn't be much of a problem. Try using cin.ignore, cin.get and reading from strings as if they were streams, this is the only simple thing that comes into my mind right now. You could of course do the whole parsing manually but that would be too much of a pain...
Ok, so here's what you should do (I'm only going to consider the "team1#1@0#team2" part):
  • Create a stringstream named, say, "ss", to use for both reading and writing. You will use this to gather data from the file and then transfer it to separate variables.
  • Next, read the "team1" part: fin.get(ss, '#'); //read until '#' is found
  • Then, store it into a variable:
    Code:

    string firstTeamName;
    ss >> firstTeamName;

  • After that, you extract it's number of goals from the file: fin.get(ss,'@')
  • And then you store them:
    Code:

    int firstTeamScore;
    ss >> firstTeamScore;

  • You then apply the same procedure for the second's team score and name
  • Note that here I use "fin" as your input file stream.
Now this code is only to be used as an example; you should read the stuff at cplusplus.com before you start playing with strings and streams.

johnsfine 12-29-2008 08:09 AM

Quote:

Originally Posted by agemo (Post 3388642)
Here's an example for what you wished

That's not really an appropriate way to respond to a homework question. You should give explanations, not do the hard parts.

Of course fscanf is not a good choice for C++ input, so you also haven't given a useful answer.

Quote:

Tring to do this with streams (fstream, cin, cout) is way more tedious, and also slower.
Wrong. There is no significant difference in speed and using fstream is the right answer for this assignment.

Quote:

Originally Posted by smasher (Post 3389592)
well.. am stuck with this part which is how to get the data from ( team1#1@0#team2 ) where i have to extract 2 team names and 2 results

I would use stream input just to read entire lines into std::string objects. Then I would use various std::string methods to pick the strings apart into the required information.

Quote:

Originally Posted by agemo (Post 3389711)
Create a stringstream

Using stringstream is often a good alternative to using std::string methods to pick apart (parse) input.

As compared to using fstream methods to parse directly from the original input, using stringstream lets you layer the parsing. That lets you do things like:
  • filtering out the // comments with common code before doing the context specific parsing
  • Splitting on delimiters (maybe # and @) before other parsing

For this particular input, my own opinion is that stringstream does not contribute enough to justify the extra effort of using it. As I said above, I would parse the data more directly from the std::string of each line. But that decision would be a close call (as opposed to fscanf, which is just wrong for a C++ homework assignment and even more so for most professional C++ programming).

agemo 12-29-2008 12:31 PM

Quote:

Originally Posted by johnsfine (Post 3390328)
Wrong. There is no significant difference in speed and using fstream is the right answer for this assignment.

Erm.. not quite: on big files de difference between fscanf and reading from streams becomes significant. Not to mention that in some cases (for example you have two million numbers on a single line), it's better to store the line in a buffer and then parse it; so sometimes, even scanf is slow.

Quote:

Originally Posted by johnsfine (Post 3390328)
(as opposed to fscanf, which is just wrong for a C++ homework assignment and even more so for most professional C++ programming).

Yes, sorry, at first I didn't consider that it might be a C++ homework.
<semi-off> generally I use C++ because it's object-oriented, but I prefer some C functions simply because they are faster.

jiml8 12-29-2008 07:55 PM

Quote:

Originally Posted by johnsfine (Post 3390328)
That's not really an appropriate way to respond to a homework question. You should give explanations, not do the hard parts.

I agree. I didn't post back on this thread because OP used the "plagiarism" excuse to avoid providing code snippets that would tell what he has tried and where he is stuck.


All times are GMT -5. The time now is 08:00 PM.