-3

It's been a while since I have worked in C++, I am helping a friend.

Is there a way without pointers return number of lines to a const int for use in a for loop?

I know I can do it with pointers but he has not learned them in class yet and I am not morally allowed to teach him anything the professor hasn't.

Example:

int numLines = sizeOfFile(inputFile);
for(int i = 0, i < numLines; i++){
  //code here
}

EDIT: my fault I was moving fast to code this thing. I am helping him today I want to have a finished project so I can work off of it while helping him. The reason I need a constant int is so I can set array to that size not just for a for loop. the array is the problem.

Trend
  • 5
  • 4

2 Answers2

1

In the simplest case you're just looking for the number of '\n' characters in the file.

So let's say that you've successfully opened the file to: ifstream pFile then you can use an istreambuf_iterator to count those:

const auto numLines = count(istreambuf_iterator<char>(pFile), istreambuf_iterator<char>(), '\n')

A couple comments here:

  1. The this count operation will consume everything in pFile's buffer, meaning you'll need to call pFile.seekg(0, ios_base::beg)
  2. Picking and choosing values to read from an ifstream indicates a bad smell in code. It's likely that the file format was improperly conceived, or that the program will subsequently need to re-stream the remainder of file contents. The 2nd option seems to be true in your case, as you seek to illegally set the size of an array with a value found at runtime:

The reason I need a constant int is so I can set array to that size

EDIT:

When you say you want to use numLines to "right an array"[sic], my assumption is that the only reason that you would have needed your array to be that size is that you're going to stream each line from a file into your container, that is you're going to stream the entire file once to calculate the size then stream the entire file again to populate your container. Here's what you should do instead:

vector<string> lines;

for(string line; getline(pFiles, line);) {
    lines.push_back(line);
}

Now lines will contain your entire file, with each element being a line. If numLines would have been important to you, instead you can use size(lines).

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • @Quentin Thanks. Clearly I hadn't clicked build yet on my browser ;) – Jonathan Mee Dec 05 '16 at 12:59
  • I need to use the const int in an array not just the for loop i forgot to mention that. I am working fast here meeting with him at 3pm its 8 am now. Want to be done quick – Trend Dec 05 '16 at 13:10
  • @Trend So my understanding of what you're trying to accomplish here is to store each line of the file in an array, is that correct? – Jonathan Mee Dec 05 '16 at 13:15
  • So I am gonna read the file and count the lines. That will be the number of record/ grades. I want to set that number, which is returned from sizeOfFile(), to a const int so I can then use it to set a array and also in a for loop to write said array and then write a report card and also output to the screen. – Trend Dec 05 '16 at 13:24
1

You can initialize a const int just the same as you would initialize a regular int. The difference with a const int is that you cannot re-assign after initialization.

const int numLines = sizeOfFile(inputFile);
for(int i = 0, i < numLines; i++){
  //code here
}
Karl Nicoll
  • 16,090
  • 3
  • 51
  • 65
  • That's initialization, not assignment. You cannot assign a `const` object, but of course you do initialize it (once). – Quentin Dec 05 '16 at 12:59
  • @Quentin - Fair point, I've corrected the terminology in my answer. – Karl Nicoll Dec 05 '16 at 13:00
  • I need to use the returned value in an array forgot to mention that – Trend Dec 05 '16 at 13:09
  • @Trend - It's hard to figure out what you're trying to do here. If you want to set your file size as a value in an array, it cannot be done. Array values are initialized upon declaration, so an array of `const int` doesn't make sense. You might be able to use a `std::vector` object and write your values into there, and that is essentially an array wrapped in C++ goodness. If you want to set the array size to `numLines`, you cannot do it unless you use pointers or `std::vector` (which also uses pointers). – Karl Nicoll Dec 05 '16 at 13:53
  • Yeah I figures arrays need a constant value. The kid I am helping hasn't learned pointers. I'll get the exact wording of the assignment for this part. But I think it nerd to be flexible array size. – Trend Dec 05 '16 at 15:04
  • @Trend - Gotta go with pointers or `std::vector` then. If your friend is able to just use C (instead of C++), have a look at [variable length arrays (VLA)](http://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard). – Karl Nicoll Dec 05 '16 at 15:09
  • So the professor said he could use vectors. I infact never took the time to learn them lol so for the past few hours I have been learning vectors lol. Is push back the only way to insert data? ArrayLists are so much easier. – Trend Dec 05 '16 at 19:11
  • @Trend - you can use push_back to add to the end, and insert to add a value to the start or middle. There are more ways to do it, but they're probably beyond the scope of what is being taught in class. – Karl Nicoll Dec 05 '16 at 19:18
  • @KarlNicoll so push_back adds to the end? So now the issue is with out pointers I want to use said vector in another function. For example I want to print avector out from another function. Pass by reference doesn't work. So i have to do it pass by value. Does that mean i need to put the funtion in a for loor and save the return value to a new vector? Or can i just send the entire vector through the argument. Again I am learning so dont be hard on my lack of knowledge – Trend Dec 07 '16 at 20:56
  • @Trend - Pass by reference *should* work, this would make your print function look like this: `printVector(const std::vector &vec)` (replace `blah` with the type being stored in the vector. You can also pass by value which will do a full copy of the vector: `printVector(const std::vector vec)`. Whichever way you do it, you do not need to copy the vector manually. You can just pass your original vector to the function and it will handle any copies automatically. – Karl Nicoll Dec 08 '16 at 14:53
  • Thanks for your help man, turns out my dumb ass forgot to make them static in the function. – Trend Dec 09 '16 at 09:24