I'm having some issues when trying to read in some values to a dynamically allocated array. Everything looks okay to me, but when the code is run, only the last entry into the array is shown. The code is below. If you could give me some recommendations I would appreciate it.
ifstream infile;
infile.open("MovieStatistics.txt");
int numOfStudents = 0;
string first, last, line;
int movies;
int *numMovies = nullptr;
string *names = nullptr;
if (!infile) {
cout << "Error opening file";
} else {
while (getline(infile, line)) {
numOfStudents++;
stringstream ss(line);
ss >> first >> last >> movies;
}
numMovies = new int[numOfStudents];
names = new string[numOfStudents];
}
for (int i = 0; i < numOfStudents; i++) {
names[i] = first + " " + last;
numMovies[i] = movies;
}
Your problem is you assign first and last inside the read loop but you don't store the values in an array or vector so they contain the last values.
To get it to work you could edit the code to:
ifstream infile;
infile.open("data.txt");
int numOfStudents = 0;
string first, last, line;
int movies;
int *numMovies = nullptr;
string *names = nullptr;
// get the number of students
while (getline(infile, line))
numOfStudents++;
numMovies = new int[numOfStudents];
names = new string[numOfStudents];
// clear the buffer
infile.clear();
infile.seekg(0, ios::beg);
int i = 0;
while(getline(infile, line)){
stringstream ss(line);
ss >> first >> last >> movies;
names[i] = first + " " + last;
numMovies[i] = movies;
++i;
}
for(int i = 0; i < numOfStudents; i++)
cout << names[i] << endl;
// don't forget to free memory:
delete[] movies;
delete[] names;
infile.close();
What I recommend is to use class vector:
std::ifstream infile("data.txt");
std::string sLine;
std::vector<std::string> vecNames;
while(getline(infile, sLine))
vecNames.push_back(sLine);
auto size = vecNames.size();
//for(auto x : vecNames)
// std::cout << x << std::endl;
for(int i(0); i != size; ++i)
std::cout << vecNames[i] << std::endl;
infile.close();
So you loop over the file, repeatedly reading data into first, last and movies — overwriting the previous values each time.
Much later, you take the current value of those variables, and write it to your dynamic arrays numOfStudents times.
You probably want to rewind the stream and loop over the file again so that you can pull out all the data; you never actually stored each sample the first time around.
Related
I am trying to read input.txt file, and trying to put each line into the array as string (later on I will use each element of array in initializing obj that's why I am putting each line into the array).
string* ptr = new string;
// Read Mode for Input
fstream input;
input.open("input.txt", ios::in);
int size = 0;
if (input.is_open()) {
string line;
while (getline(input, line)) {
cout << line << endl;
ptr[size] = line;
size++;
}
input.close();
}
for (int i = 0; i < size-1; i++) {
cout << "array: " << ptr[i] << endl;
}
I am getting error as:
Proxy Allocated, drain it
Don't use arrays; use std::vector. The std::vector behaves like an array and uses Dynamic Memory:
std::string s;
std::vector<std::string> database;
while (std::getline(input, s))
{
database.push_back(s);
}
Keep it simple. :-)
As was noted in the comments, if you don't know how many lines in the file then you need a container which grows on request at runtime. The natural choice is std::vector :
std::fstream input("input.txt", std::ios::in);
std::vector<std::string> lines;
std::string line;
while (getline(input, line)) {
lines.push_back(line); // std::vector allocates more memory if needed
}
for (int i = 0; i < lines.size(); i++) {
std::cout << lines[i] << std::endl;
}
im a Student and new to this site. I want to split my txt file with my highscore data back to my Highscore List.
The txt file stores my Highscore like name:score
My parsing is not working and i dont know why?
I just want to split it to name and score again and then put it in my HighscoreList.
If you have any question about the code just ask :)
#include "highscore.h"
highscore::highscore(){
}
struct highscore::Player{
string spielerName;
int score;
};
void highscore::writeHighscore(string name, int score ,int playerNumberx){
Player HighscoreListe[100];
for(int i=0;i<=99;i++){
HighscoreListe[i].score = {0};
}
for(int i=0;i<=99;i++){
HighscoreListe[i].spielerName = "leer";
}
HighscoreListe[playerNumberx].spielerName = name;
HighscoreListe[playerNumberx].score = score;
int i, j,temp;
string temp1;
ifstream myfile("scores.txt");
string line;
//heres the point where i need help!!
if (myfile.is_open()){
int z=0;
while(getline(myfile, line)){
string name1;
string score1;
int d = 20;
while(line[z] != ':'){
name1 += line[z];
z++;
}
z = z+2;
while(line[z] != '\0'){
score1 += line[z];
z++;
}
HighscoreListe[d].spielerName = name;
HighscoreListe[d].score = score;
d++;
}
myfile.close();
}else cout << "Unable to open file" << endl;
for(i = 0; i<100; i++) {
for(j = i+1; j<100; j++)
{
if(HighscoreListe[j].score < HighscoreListe[i].score) {
temp = HighscoreListe[i].score;
temp1 = HighscoreListe[i].spielerName;
HighscoreListe[i].score = HighscoreListe[j].score;
HighscoreListe[i].spielerName = HighscoreListe[j].spielerName;
HighscoreListe[j].score = temp;
HighscoreListe[j].spielerName = temp1;
}
}
}
ofstream myfilex("scores.txt");
if (myfilex.is_open()){
for(int i = 99;i>89;i--){
myfilex << HighscoreListe[i].spielerName << ":" << HighscoreListe[i].score<<endl;
}
myfilex.close();
}
else cout << "Unable to open file" << endl;
}
void highscore::readHighscore(){
string line;
ifstream myfile("scores.txt");
if (myfile.is_open()){
while(getline(myfile, line)){
cout << line << endl;
}
}
else cout << "Unable to open file" << endl;
}
Make a >> overload for highscore::Player.
In the >> overload
Use std::getline to read a line from the input stream.
Create a std::istringstream out of the line.
Use std::getline to read up to the : from the istringstream into a local string name;.
Use another std::getline to read the rest of the line into a string.
Convert the string into an int with std::stoi and store into a local int score;. Make sure you provide a pos argument.
Ensure that the entire string was converted by comparting the pos argument with the string's length.
If nothing went wrong, store name and score into the highscore::Player passed by the caller. Otherwise, set the failbit on the input stream with setstate
return the input stream.
Now the reading code should be something simple like
int scorecount = 0;
while (myfile >> HighscoreListe[scorecount])
{
scorecount++;
}
For some reason the full lines from my input file are not reading into the array, only the first word in each line. I am currently using the getline call, but I am not sure why it is not working. Here is the what I have for the call to populate the array. The txt file is a list of songs.
const int numTracks = 25;
string tracks[numTracks];
int count = 0, results;
string track, END;
cout << "Reading SetList.txt into array" << endl;
ifstream inputFile;
inputFile.open("SetList.txt");
while (count < numTracks && inputFile >> tracks[count])
{
count++;
getline(inputFile, track);
}
inputFile.close();
while (count < numTracks && inputFile >> tracks[count])
The >> operator reads a single word. And this code reads this single word into the vector in question.
getline(inputFile, track);
True, you're using getline(). To read the rest of the line, after the initial word, into some unrelated variable called track. track appears to be a very bored std::string that, apparently, gets overwritten on every iteration of the loop, and is otherwise completely ignored.
Your loop is using the operator>> to read the file into the array. That operator reads one word at a time. You need to remove that operator completely and use std::getline() to fill the array, eg:
const int numTracks = 25;
std::string tracks[numTracks];
int count = 0;
std::cout << "Reading SetList.txt into array" << std::endl;
std::ifstream inputFile;
inputFile.open("SetList.txt");
while (count < numTracks)
{
if (!std::getline(inputFile, tracks[count])) break;
count++;
}
inputFile.close();
Or:
const int numTracks = 25;
std::string tracks[numTracks];
int count = 0;
std::cout << "Reading SetList.txt into array" << std::endl;
std::ifstream inputFile;
inputFile.open("SetList.txt");
while ((count < numTracks) && (std::getline(inputFile, tracks[count]))
{
count++;
}
inputFile.close();
Alternatively, consider using a std::vector instead of a fixed array, then you can use std::istream_iterator and std::back_inserter to get rid of the manual loop completely:
class line : public std::string {}
std::istream& operator>>(std::istream &is, line &l)
{
return std::getline(is, l);
}
...
std::vector<std::string> tracks;
std::cout << "Reading SetList.txt into array" << std::endl;
std::ifstream inputFile;
inputFile.open("SetList.txt");
std::copy(
std::istream_iterator<line>(inputFile),
std::istream_iterator<line>(),
std::back_inserter(tracks)
);
inputFile.close();
I need help in c++ with reading text from file into dynamic array.
File
Regbis
Vardenis Paverdenis
Jonas Puikuolis
Gediminas Jonaitis
Futbolas
Tadas Pilkius
Justas Julis
Tenisas
Ricerdas Berankis
I tried like this and another way with while and getline s.empty but it didn't work for me.
using namespace std;
struct struktura{
char team;
char lastname;
char firstname;
} sarasas[999];
int main()
{
char x [200];
int kiek;
ifstream duomenys;
duomenys.open("duom.txt");
int row, col;
while (!duomenys.eof())
{
cout << "How many teams" << endl;
cin >> row;
int **a = new int *[row];
for (int i = 0; i < row; i++)
{
cin >> col;
a[i] = new int[col];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
duomenys >> a[i][j];
cout << a[i][j] << " ";
}
cout << endl;
}
}
system("Pause");
return 0;
}
Okay, this has quite a few problems. I'd start with using std::string for the strings, and std::vector for the dynamic array.
Then I'd work at defining the data structures at least halfway reasonably. I think the general idea is something like this:
struct team {
std::string name;
std::vector<std::string> players;
};
Then I'd define an operator>> for a team, something like this:
std::istream &operator>>(std::istream &is, team &t) {
std::vector<std::string> players;
std::string temp;
// If we can't read a team name, return signaling failure:
if (!std::getline(is, temp))
return is;
// save the team name
t.name = temp;
// and read the player's names:
while (std::getline(is, temp)) {
if (temp.empty()) // empty line--end of this team's players
break;
players.push_back(temp);
}
t.players = players; // Write the player's names into the destination
is.clear(); // and signal success, since we read a team's data
return is;
}
From there, we can read all the teams in a file:
std::ifstream in("teams.txt");
std::vector<team> teams { std::istream_iterator<team>{in},
std::istream_iterator<team>{} };
void start ( string fname )
{
string FirstElement;
int count = 0 ;
fstream Infile;
Infile.open( fname.c_str(), ios::in ); // Open the input file
while(!Infile.eof()) // using while to look for the total lines
{
count++;
}
//read to the array
string data_array[]; //initializing an array
for(int i=0; !Infile.eof(); i++){
Infile >> data_array[i]; // storing the value read from file to array
}
//Display the array
// for(int i=1; i<11; i++){
// cout << data_array[i] << endl;
//}
cout << data_array[0] << endl;
cout << count << endl;
return;
}
I have a text files contain values lines by lines
My plan was to use the while loop to do a total count of the lines
and place it in the "string data_array[]" but somehow it doesnt work that way.
anyone can advise me on how can I make it in a way that It can have a flexible storage size going according to the numbers of values in the text files? thanks
For flexible storage as you call it, you may use STL's container, such as std::vector<T> or std::list<T>. Other issues are highlighted in inline comments.
// pass by reference
void start(const std::string& fname)
{
// use std::ifstream, instead of std::fstream(..., std::ios::in);
std::ifstream Infile(fname.c_str());
// prefer std::vector to raw array
std::vector<std::string> data_array;
std::string line;
// read line by line
while (std::getline(Infile, line))
{
data_array.push_back(line); // store each line
}
// print out size
std::cout << data_array.size() << std::endl;
// display the array, note: indexing starts from 0 not 1 !
for(int i = 0; i < data_array.size(); ++i)
{
std::cout << data_array[i] << std::endl;
}
}