Ok, well I have an assignment, and I'll be needing some help.

First off, I need help on counting the number of from a text file.
I'm not sure if I should do a loop eg :

for (j=0, j<26; j++)

or there may be an easier way. I have looked around Google, and all I don't really get anything that speaks out clearly to me. However I have read mentions to the use of getline.

I know I need

#include <fstream>
ifstream inData;

inData.open(music.txt);

at the beginning, and considering this part of my program will not be in main (it'll be as a void), I'll need help with this type of thing too.

The little tidbit of the loop is to also deal with the alphabetic characters, however I'm doubting it deals with the numerics as well, if I stick with a loop, do I have to do something else apart from j<36?

This is just the first part of what I need done, I'll ask other questions later on.

Recommended Answers

All 15 Replies

If you need to count just lines in a file, you can use:

while (!dataFile.eof()) {
[INDENT]getline(dataFile, codeLine);
linesNumber++;[/INDENT]
}

codeLine - string type.

Ok, so I could just use the eof function for the total lines. Thanks.
So with using my input file as music.txt, should it look like

while (music.txt.eof()) {
getline(music.txt, codeLine);
linesNumber++;
}

I haven't really used eof's before, so I may just need to use your supplied instead, and not change anything inside it, but change things outside.

Ok, second part.(Clarification)
The input file will have entries grouped into 3 fields, separated by commas. (eg, field1, field2, field3)
What I need to get is the field3 of all entries, and add them up (forgot to mention they will all be ints). The calculations for their end result I already have.
Should I be using the

cin.ignore

, and if so, how would I alter it so it can ignore the first 2 fields (they are separated by commas, not spaces in the input file, and I need it to run like that) and just take the third field?

You shoud write:

#include <fstream>
ifstream inData;
string codeLine;
int linesNumber;

[INDENT]inData.open(music.txt);

while (! inData.eof()) {
getline(inData, codeLine);
linesNumber++;[/INDENT]
}

If you need just a third part, when you get a codeLine you should check its elements (going though the string in codeLine[0], codeLine[1]...codeLine[n] way) and count how many commas you went through. If you count 2, then it's the start of the third part.

Don't know much about "ignore", but:
std::cin.ignore(<numberOfCharacters>, ',');
means that numberOfCharacters or everything to the first comma (depends on what will be reached first) will be ignored. So maybe it doesn't suit here.

Member Avatar for iamthwee

You could do this many ways.

I would read in the line and use the comma as a delimiter. push them into a vector and convert the third element from a string to an int.

Avoid while (file.eof()) {...} loop condition, it's a wrong pattern. Check file.eof() AFTER an input operation only.

ifstream file(filename);
int n = 0;
string line;
while (getline(f,line)) {
  // Now you have a line!
  n++;
}

The simplest way to test C++ stream state:

if (!file) { // don't call i/o ops on the file!
   ...
}
// or
if (file) { // that's OK, file stream is ready
   ...
}

std::getline(file,...) returns a reference to file, that's why the 1st snippet above is OK.

Oh, well my head has had problems getting around things this half-year.
Thanks for all the help guys. I'm a bit tired, so I'll carefully read the replies tomorrow. I suppose I could do the ignores for the first 2 commas, just have to make sure it doesn't so anything funky due to actual characters being between them.
Still not entirely solved(so don't mark it as such), since I'll be asking more later, and I don't want to add another thread.

Aha!, got the line counter to work.
And for other people who may or may not need help, this is what I have:

ifstream infile;
	ofstream outfile;
	infile.open("file.txt");
	ifstream file("file.txt");

	int n = 0;
	string line;
	while (getline(infile,line))
	{
	  // Now you have a line!
	  n++;
	}

Edit as necessary as the declarations are just for this part.
It will also ignore a blank line if it appears in the text file.

Ok, so if I want to find the 3rd field of every line(each field is separated by a comma I may just need to use the getline function again, however with a header of <string>?
I would also need to add all those values into one variable if possible.
Can't get my head around C++ in general, sorry if i'm being a slight nuisance.

Use stringstreams to parse lines:

// STL dependencies:
#include <fstream>
#include <string>
#include <sstream>

int Get3rd(const char* fname)
{
    if (!fname) // always test pointers!
        return -1;
    ifstream f(fname);
    int lines, fields = 0;
    string line;
    string field; // declare desired type...

    for (lines = 0; getline(f,line); lines++) {
        if (size_t sz = line.size()) {// non-empty line
            istringstream is(line);
            if (is.ignore(sz,',') // skip 1st field
            &&  is.ignore(sz,',') // skip 2nd field
            && (is >> field)) {   // get  3rd field
                cout << field << '\n';//(non-empty)
                fields++;
            }
        }
    }
    cout << "Lines: " << lines << " fields " << fields << endl;
    return fields;
}

It's not the most effective code but it works.
Pay attention to the 1st if condition in for loop: condition in C++ is not expression only...

Not sure if that's what I'm really looking for.

I was leaning towards more of the

std::cin.ignore(500, ',' );

. I see the fault that it may ignore 500 characters including the commas and hence also ignoring the 3rd field.

However I think that only deals with what is given up to the first comma, and not the second. Is there a configuration that ignores the field, comma, field, comma and then takes the third field, stores it into a "pool/variable" and loops it onto the next line?

Ok, I had some help from my brother, he recommended using a looped getchar on the line until I hit a comma, then it loops again until I hit the second comma.
After it hits the second comma, it'll getchar again for the first digit of the third field. From there, it'll check if the next char is a comma, if it is, exit loop and add digit to the pool. If it isn't, it'll multiply the first digit by 10 and add the next digit, and so forth.

This loop of (looping to find part after first 2 commas then(looping to find all digits in 3rd field)) will be repeated each line and new line [will be using the \n marker].
I may or may not connect it with the total line result I got just now.

>Is there a configuration that ignores the field, comma, field, comma and then takes the third field, stores it into a "pool/variable" and loops it onto the next line?
Of course, it's exactly my code in the previous post.
It seems you don't understand C++ programs ;)

Of course I don't understand C++, I think I mentioned that twice on some of my own posts.

Would be more helpful to give a line-by-line explanation for some of the parts of the code, y'know, like teaching a man to fish instead of giving him the fish.
After looking back on the code, there is a few things I hadn't really used before, should also mention that at the end of every line, there's a comma, then the newline. Also, I'd pretty much be replacing "fname" with music.txt, but unsure of any other configurations.

For the getchar, I wanted to use it, even though it would take longer, but I was unsure of the implementation of it, let's say for it to get to a certain character and as the way I was designing it, for the getchar to be in it's own loop, just getting the characters before the two commas (using the commas as a limiter), then with the third field, get those chars, store them into an other variable and keep going.

Ok ArkM, sorry about that, had a group assignment due very soon and the other members of my group didn't email me their answers until very late. It's kinda like waiting for a good MA 15+ movie and getting a G movie or somewhat.

After changing around your code, I was able to get most of what I needed, also managed to make a configuration so that the values are added into a pool. Currently manipulating the pool for my desired answers.

Well I've got that first bit down pat, however, when needing to run another process (or loop the initial process), it won't work. I believe the problem is in the more recent code given. I've added a cout after the process to test, and that cout did not show, hence why the process provided was faulty. Perhaps it left something open and since I don't have the in-depth knowledge, I don't know what the f is going wrong.

Ok, now this is turning into a progress blog funnily enough.

I have what my first part requires down, just had to return main(); instead of return 0;.


If anyone is willing to help me do this next bit:
Assign each line of a text file (already have number of lines) a number and randomly generate a list populated by a number of entries specified by the user. This generation mustn't have the same entry twice or more in any list.

(Well, that's the way I'm thinking about it at least, if there's a better way, feel free to post it up)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.