1

I began learning strings yesterday and wanted to manipulate it around by filling it with a text from a text file. However, upon filling it the cstring array only prints out the last word of the text file. I am a complete beginner, so I hope you can keep this beginner friendly. The lines I want to print from the file are: "Hello World from UAE" - First line "I like to program" - Second line Now I did look around and eventually found a way and that is to use std::skipary or something like that but that did not print it the way I had envisioned, it prints letter by letter and skips each line in doing so. here is my code:

#include <fstream>
#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;

 int main() {

ifstream myfile;
myfile.open("output.txt");
int vowels = 0, spaces = 0, upper = 0, lower = 0;
//check for error
if (myfile.fail()) {
    cout << "Error opening file: ";
    exit(1);
}
char statement[100];

while (!myfile.eof()) {
    myfile >> statement;
}
for (int i = 0; i < 30; ++i) {
    cout << statement << " ";
}
Jos
  • 65
  • 6
  • 2
    [Why is `iostream::eof` inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Evg May 07 '20 at 09:46
  • The statement `myfile >> statement;` will ***overwrite*** the contents of `statement` each iteration of your loop. Perhaps what you need an an array (or better yet a `std::vector`) to fill? – Some programmer dude May 07 '20 at 09:47
  • *"I began learning strings [...]"* Strings in C++ are `std::string`, not `char[]`. – nada May 07 '20 at 10:09
  • @nada cstrings specifically, I have it in my title of the question. Hence using char[] – Jos May 07 '20 at 11:08
  • Why would you want to do that? Lean C++ stuff, if you want to learn C++. Not C stuff. – nada May 07 '20 at 13:04

2 Answers2

1

I'm not exactly sure what you try to do with output.txt's contents, but a clean way to read through a file's contents using C++ Strings goes like this:

if (std::ifstream in("output.txt"); in.good()) {

    for (std::string line; std::getline(in, line); ) {

        // do something with line
        std::cout << line << '\n';
    }

}

You wouldn't want to use char[] for that, in fact raw char arrays are hardly ever useful in modern C++.

Also - As you can see, it's much more concise to check if the stream is good than checking for std::ifstream::fail() and std::ifstream::eof(). Be optimistic! :)

nada
  • 1,995
  • 2
  • 11
  • 21
  • And if the OP wants to read "words" rather then lines, the inner loop condition could be replaced with `in >> line`. – Some programmer dude May 07 '20 at 13:24
  • @Someprogrammerdude Is your approach rock solid? Actually never did it like you suggest. I'd read the whole line and [tokenize it](https://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c#55680). – nada May 07 '20 at 14:32
0

Whenever you encounter output issues - either wrong or no output, the best practise is to add print (cout) statements wherever data change is occurring.

So I first modified your code as follows:

while (!myfile.eof()) {
    myfile >> statement;
    std::cout<<statement;
}

This way, the output I got was - all lines are printed but the last line gets printed twice.

So,

  1. We understood that data is being read correctly and stored in statement.

  2. This raises 2 questions. One is your question, other is why last line is printed twice.

To answer your question exactly, in every loop iteration, you're reading the text completely into statement. You're overwriting existing value. So whatever value you read last is only stored.

Once you fix that, you might come across the second question. It's very common and I myself came across that issue long back. So I'm gonna answer that as well.

Let's say your file has 3 lines:

line1

line2

line3

Initially your file control (pointer) is at the beginning, exactly where line 1 starts. After iterations when it comes to line3, we know it's last line as we input the data. But the loop control doesn't know that. For all it knows, there could be a million more lines. Only after it enters the loop condition THE NEXT TIME will it come to know that the file has ended. So the final value will be printed twice.

sonofel
  • 72
  • 1
  • 7