1

I have a script which reads text file into a vector.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

struct Items
{
    string Name;
    int Number1;
    double Number2;
};

int main()
{
    ifstream file("file4.txt"); 
    vector<Items> player_data;
    Items player_info;
    while (file >> player_info.Name >> player_info.Number1 >> player_info.Number2) { 
        player_data.push_back(player_info);
    }

    for (auto &i : player_data) {
        std::cout << i.Name << ", " << i.Number1 << ", " << i.Number2 << endl;
    }
}

The file4.txt contains as follows:

Wogger Wabbit
2
6.2
Bilbo Baggins
111
81.3
Mary Poppins
29
154.8

How can I display the data properly? How could I give the separation which is a line break ('\n')?

Gabriel90
  • 101
  • 7
  • 3
    Can you please clarify what you are trying to achieve, and what happens instead right now? My impression is that you only need to replace the `,`s in the output line with `\n`. This seems a bit too simple, so I guess I am misunderstanding... – BoBTFish Jun 02 '20 at 07:08
  • 1
    Can you post an example what do you expect to be printed? – RvdK Jun 02 '20 at 07:09
  • 1
    "How can I display the data properly? ". In which way fails the shown code to display properly? – RubberBee Jun 02 '20 at 07:10
  • 1
    I send a print screen: https://imgur.com/a/37OdYqj. The problem is not showing data on command line. – Gabriel90 Jun 02 '20 at 07:14
  • 1
    @Gabriel90 It seems most likely that the problem is somehow when you are reading from the file, so there is actually no data to print out. Are you sure the file is opened correctly? Maybe you have the name wrong, or it is in a different folder? – BoBTFish Jun 02 '20 at 07:16
  • are you sure that you read the file? – yaodav Jun 02 '20 at 07:17
  • @BoBTFish The file name and location are correct, i don't know what the problem might be. Is there a problem with Dev-C ++? – Gabriel90 Jun 02 '20 at 07:21
  • @Gabriel90 did you check your code with Debagger? – yaodav Jun 02 '20 at 07:22
  • @Gabriel90 You can check if the file opened correctly like this: `if ( ! file ) { std::cerr << "didn't open!\n" ; } else { // do the reading }` – BoBTFish Jun 02 '20 at 07:29
  • @yaodav Please think carefully about what you put in your comments - this asker is obviously an absolute beginner, and I think your comments could seem more dismissive rather than giving helpful ideas how to proceed. Maybe you can point to specific pieces of code that may be wrong, or suggest what to look for in a debugger (maybe with a link to an intro guide?) – BoBTFish Jun 02 '20 at 07:40
  • @BoBTFish thank you for your comment, I didn't think that my comment can sound dismissive and thy didn't intend to sound like one, il pay more attention next time :) – yaodav Jun 02 '20 at 07:45
  • @yaodav No problem, thanks for taking it constructively :) I guess English is not your first language? It is sometimes hard to realise how your tone might come across in a short comment, even for a native speaker like me. – BoBTFish Jun 02 '20 at 07:47
  • @BoBTFish I already know what the problem was. The error was in the names, the program only works if there is no space in the names but a hyphen or bottom line (for example: "Wogger_Wabbit" instead of "Wogger Wabbit"). – Gabriel90 Jun 02 '20 at 07:59
  • @Gabriel90 Of course! This is a good time for you to learn to prefer using [`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline#Example) (the example even demonstrates reading a name with spaces in it). – BoBTFish Jun 02 '20 at 08:02

3 Answers3

3

You have a few problems with your code; this solution works but it's not elegant. I'm sure the people here can give you or direct you to a more elegant one :)

First - after opening a file you need to check if it is open

Second - it is better to use std::getline() to read from the file because it gets the whole line. The >> stops when it gets to space.

Also, try not to use using namespace std

EDIT

added print of the error if the file doesn't open

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

using namespace std;

struct Items
{
  string Name;
  int Number1;
  double Number2;
};

int main()
{
  ifstream file("text4.text");
  if(!file.is_open()) // <- check if file opened correctly
  {
    std::cout << std::strerror(errno); // <- print the reason why the file didnt open 
    return 0;
  }
  vector<Items> player_data;
  Items player_info;
  std::string line;
 while(std::getline(file,line)) // <-- read lines and stop when the file is finished 
 {
   player_info.Name = line;
   std::getline(file,line);
   player_info.Number1 = stoi(line);
   std::getline(file,line);
   player_info.Number2 = stod(line);
   player_data.push_back(player_info);
 }


  for (auto &i : player_data) {
    std::cout << i.Name << ", " << i.Number1 << ", " << i.Number2 << endl;
  }
}
yaodav
  • 1,126
  • 12
  • 34
  • 1
    Can I suggest adding some code to help you spot when the file didn't open correctly? You could print out a log line, or return a different error code (`0` is supposed to be used for success, so you could `return 1;` to indicate a failure). – BoBTFish Jun 02 '20 at 07:57
1

From your description, I am assuming you want to print the outputs line by line. So use '\n' instead of comma:

std::cout << i.Name << "\n" << i.Number1 << "\n" << i.Number2 << endl;

  • 1
    I send a print screen: https://imgur.com/a/37OdYqj. The problem is not showing data on command line. – Gabriel90 Jun 02 '20 at 07:16
  • 2
    Because there are no elements in the player_data. Print the size and see. The problem is in line `while (file >> player_info.Name >> player_info.Number1 >> player_info.Number2)`. The file is open but not reading properly. Fix it and it will work. – Prabhakar Tayenjam Jun 02 '20 at 07:35
1

You can solve your issue in the following way -

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;

struct Items {
    string Name;
    int Number1;
    double Number2;
};

int main() {
    ifstream file("file4.txt");
    vector<Items> player_data;
    Items player_info;
    while (getline(file,player_info.Name)) {
        file>>player_info.Number1>>player_info.Number2;
        player_data.push_back(player_info);
        file.ignore();

    }
    file.close();
    for (auto &i : player_data) {
        cout << i.Name << ", " << i.Number1 << ", " << i.Number2 << endl;
    }
}

Now let's investigate what's the catch is here.

  1. First of all, your name can contain blank space between them and you can't take input a string with empty space using >> operator. You have to you getline() function to take input string with empty spaces. This function take input the whole line of the input file as a string.
  2. Secondly, your other two inputs are integers or other primitive data types so you can take input them using >> operator. In the above code, these two input is inside the while loop.
  3. Lastly and most important file.ignore(). >> operator terminates input when it encounters a blank space ' ', newline '\n' character. So after taking the input of player_info.Number2 there is a newline character in the input file so >> operator stop here but the newline character remains in the input buffer and getline() function is very sensitive to newline and blank space character so this creates a problem. So you have to somehow remove or ignore the buffer's newline character. file.ignore() do this job for you.
Tanmoy Datta
  • 1,604
  • 1
  • 17
  • 15