tags:

views:

111

answers:

4

Hi I have a file with some text in it. Is there some easy way to get the number of lines in the file without traversing through the file?

I also need to put the lines of the file into a vector. I am new to C++ but I think vector is like ArrayList in java so I wanted to use a vector and insert things into it. So how would I do it?

Thanks.

A: 

1) No way to find number of lines without reading the file.

2) Take a look at getline function from the C++ Standard Library. Something like:

string line;
fstream file;
vector <string> vec;
...   
while (getline(file, line)) vec.push_back(line);
Nemanja Trifunovic
+6  A: 

There is no way of finding the number of lines in a file without reading it. To read all lines:

1) create a std::vector of std::string

3 ) open a file for input

3) read a line as a std::string using getline()

4) if the read failed, stop

5) push the line into the vector

6) goto 3

anon
+1, although I almost marked you down for the use of goto ;)
John Knoeller
+1 You could have written it without goto :-)
Martin York
I'm suprised no-one has complained about line numbers!
anon
Which 3 should it go to? :)
Steve Fallows
The third one, obviously :-) Amazing no-one else noticed it!
anon
+2  A: 

You would need to traverse the file to detect the number of lines (or at least call a library method that traverse the file).

Here is a sample code for parsing text file, assuming that you pass the file name as an argument, by using the getline method:

#include <string>
#include <vector>
#include <fstream>
#include <iostream>

int main(int argc, char* argv[])
{
  std::vector<std::string> lines;
  std::string line;

  lines.clear();

  // open the desired file for reading
  std::ifstream infile (argv[1], std::ios_base::in);

  // read each file individually (watch out for Windows new lines)    
  while (getline(infile, line, '\n'))
  {
    // add line to vector
    lines.push_back (line);
  }
  // do anything you like with the vector.  Output the size for example:
  std::cout << "Read " << lines.size() << " lines.\n";

  return 0;
}

Update: The code could fail for many reasons (e.g. file not found, concurrent modifications to file, permission issues, etc). I'm leaving that as an exercise to the user.

notnoop
Yoy don't need the :in parameter for ifstreams - you do need to check that the file opened
anon
@Neil: If the file failed to open then getline() will fail and then cause the loop not to be entered. So checking for a failure is not required (unless you want to report it).
Martin York
@Martin Yes, I realise that. However, if you take that approach you can't differentiate between open failing an an empty file.
anon
@Neil, @Martin, I provided the code as a sketch to how it could be implemented, not to provide production-ready snippet. I added a note about the various errors that could occur.
notnoop
A: 

Traversing the file is fundamentally required to determine the number of lines, regardless of whether you do it or some library routine does it. New lines are just another character, and the file must be scanned one character at a time in its entirety to count them.

Since you have to read the lines into a vector anyways, you might as well combine the two steps:

// Read lines from input stream in into vector out
// Return the number of lines read
int getlines(std::vector<std::string>& out, std::istream& in == std::cin) {
  out.clear(); // remove any data in vector
  std::string buffer;
  while (std::getline(in, buffer))
    out.push_back(buffer);

  // return number of lines read
  return out.size();
}
meagar
1) I think you mean push_back, and 2) I'd push back and empty vector and swap.
David Lehavi