guys, I'm reading from a file and input into a vector, but I keep getting a pop up box with: "vector employees out of range!" error. It is like if I'm trying to access pass the last index in the vector, but if that's the case I don't see... any help appreciated
text file:
123 vazquez 60000
222 james 100000
333 jons 50000
444 page 40000
555 plant 40000
code:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
struct employees { int id; string lname; double salary; };
void getData(vector<employees>& list, ifstream& inf);
int i = 0;
int main()
{
string filename("file2.txt");
vector<employees> list;
ifstream inf;
inf.open(filename);
getData(list, inf);
inf.close();
for(unsigned int j = 0; j < list.size(); j++)
{
cout << list[j].id << " " << list[i].lname << endl;
}
system("pause");
return 0;
}
void getData(vector<employees>& list, ifstream& inf)
{
int i = 0;
while(inf)
{
inf >> list[i].id >> list[i].lname >> list[i].salary;
i++;
}
}
When you pass list into getData(), it has zero elements in it. You then try to access the element at index i (starting at 0), but there is no such element, hence the error.
You need to insert new elements into the container; the easiest way to do this would be to create a temporary object, read the data into that object, and then insert that object into the container.
employee e;
while (inf >> e.id >> e.lname >> e.salary)
list.push_back(e);
Note that this also fixes your incorrect input loop. In your incorrect loop, the stream could reach EOF or otherwise fail during one of the reads in the loop, but you don't detect that until after you've incremented i.
In your while loop in getData, you need to push_back an employees each time. Or you can define the >> operator for your employees class, and you wouldn't even need the getData function, you could just past an istream_iterator into the vector constructor.
Example using istream_iterator:
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
struct employee { int id; std::string lname; double salary; };
std::istream& operator>>(std::istream& is, employee& e) {
return is >> e.id >> e.lname >> e.salary;
}
int main() {
std::string filename("file2.txt");
std::ifstream inf;
inf.open(filename); //add error checking here
std::vector<employee> list((std::istream_iterator<employee>(inf)), std::istream_iterator<employee>());
for (std::vector<employee>::iterator iter = list.begin(); iter != list.end(); ++iter) {
std::cout << iter->id << " " << iter->lname << std::endl;
}
return 0;
}
list[i].lname should be list[j].lname
Related
Making a program that reads integers from a file and creates an array, I have that part completed however I am trying to figure out how to change the SIZE value depending on how many ints are in the file. This file has 15 integers but another file may have more and this array will not take in all the ints.
using namespace std;
const int SIZE = 15;
int intArray[SIZE];
void readData(istream& inFile) {
for (int i = 0; i < SIZE; i++){
inFile >> intArray[i];
cout << intArray[i] << " ";
}
}
int main() {
ifstream inFile;
string inFileName = "intValues.txt";
inFile.open(inFileName.c_str());
int value, count = 0;
while(inFile >> value){
count += 1;
}
cout << count;
readData(inFile);
return 0;
}
As you can see I have a while loop counting the number of ints in the file however when I assign that to the size value I was running into many different issues.
A fixed-sized array simply cannot be resized, period. If you need an array whose size can change at runtime, use std::vector instead.
More importantly, you are reading through the entire file just to count the number of integers, and then you are trying to read the values from where the previous loop left off. You are not seeking the ifstream back to the beginning of the file so you can re-read what you have already read.
Try something more like this instead:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
string inFileName = "intValues.txt";
ifstream inFile(inFileName.c_str());
int value, count = 0;
while (inFile >> value){
++count;
}
cout << count;
std::vector<int> intArray;
intArray.reserve(count);
inFile.seekg(0);
while (inFile >> value){
intArray.push_back(value);
cout << value << " ";
}
// use intArray as needed...
return 0;
}
Alternatively, don't even bother counting the integers, just let the std::vector grow as needed, eg:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
string inFileName = "intValues.txt";
ifstream inFile(inFileName.c_str());
vector<int> intArray;
int value;
while (inFile >> value){
intArray.push_back(value);
cout << value << " ";
}
// use intArray as needed...
// you an get the count from intArray.size()
return 0;
}
I am a newbie in C++. I want to get user input by using a vector. I set the vector size of 5. However, I get the infinite loop in the for loop. Please let me know if there is something wrong. Thanks in advance.
int main() {
std::string name;
std::vector<std::string> stringVector (5);
for(int i = 0 ; i < stringVector.size(); i++)
{
std::cout << "Enter the name" << std::endl;
std::getline(std::cin, name);
stringVector.push_back(name);
}
}
std::vector<std::string>::push_back() inserts a new element i.e adds a new element and makes the size increase by one, hence you have an infinite loop. Note that you want the loop to stop after reaching the size iterations but the size increases for each iteration. You can use the following instead
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main() {
std::string name;
std::vector<std::string> stringsVector (5);
for(size_t i{} ; i < stringsVector.size(); i++)
{
std::cout << "Enter the name" << std::endl;
std::getline(std::cin, name);
stringsVector[i] = name;
}
std::for_each(stringsVector.cbegin(), stringsVector.cend(), [](auto & el){std::cout << el << " ";});
}
Demo
When using object size as 5 "stringsVector (5)" no need to use pushback, else it will increase the size of the object on every loop by 1
for easy understanding using simple for loop
#include <iostream>
#include <vector>
using namespace std;
int main() {
std::string name;
std::vector<std::string> stringsVector (5);
for(size_t i= 0 ; i < stringsVector.size(); i++)
{
std::cout << "Enter the name" << std::endl;
std::getline(std::cin, name);
stringsVector[i] = name;
}
for(size_t i= 0 ; i < stringsVector.size(); i++)
{
std::cout << stringsVector[i] << " ";
}
}
after initialization of stringVector stringVector.size() = 5,
after each iteration the size is incremented by 1.
i is initialized with 0 and the condition (i < stringVector.size()) is always satisfied.
that's why You are getting infinite loop.
players.txt
2
Zlatan
Ibrahimovic
1981
4
20130110
20130117
20130122
20130208
Yohan
Cabaye
1986
1
20130301
Main.cpp
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream pFile("players.txt");
int numberOfPlayers;
string firstName;
string lastName;
int birthYear;
int numberOfMatches = 0;
string *matchDates = NULL;
matchDates = new string[];
while (pFile >> numberOfPlayers >> firstName >> lastName >> birthYear >> numberOfMatches >> matchDates)
{
for(int i = 0; i < numberOfPlayers; i++)
{
cout << firstName << endl;
cout << lastName << endl;
cout << birthYear << endl;
for(int i = 0; i < numberOfMatches; i++)
{
cout << matchDates[i] << endl;
}
}
}
delete[] matchDates;
getchar();
return 0;
}
So I want to import data from a textfile, e.g. soccer players as above or anything else, like hockey players etc. The point is to be able to use this code for all kind of sports aka it's not set to like 12 players max, amount of players should be dynamic. Well I'm already stuck here with what I thought was a dynamic array (matchDates) but I've been told that it's not and is still a static array.
matchDates should also be dynamic because some players could've 20 mathcdates, another could have five, another three and so on. In my example zlatan has four and youhan one.
Well my problem appear on line 20, posted below:
while (pFile >> numberOfPlayers >> firstName >> lastName >> birthYear >> numberOfMatches >> matchDates)
Error message when I hover over the bolded ">>" (which is underlined with red in VS)
Error no operator ">>" matches these operands
operand types are: std::basic_istream> >> std::string *
I want to print out all matchdates but it doesn't work and I'm very sure it's something to do with matchDates.
Thanks in advance and regards Adam
Use C++ class for player, stop using new and override stream operator.
See the code in action here
#include <iostream>
#include <string>
#include <deque>
#include <fstream>
#include <algorithm>
#include <iterator>
using namespace std;
class Player
{
public:
Player() : firstName(""), lastName(""), birthYear(0){}
~Player() {}
//copy ctor by default
// Operator Overloaders
friend ostream &operator <<(ostream &output, const Player p);
friend istream &operator >>(istream &input, Player &p);
private:
string firstName;
string lastName;
int birthYear;
deque<string> matchDates;
};
ostream& operator <<( ostream& output, const Player p )
{
output << p.firstName << " " << p.lastName << " etc ...";
return output;
}
istream& operator >>( istream& input, Player &p )
{
input >> p.firstName;
input >> p.lastName;
input >> p.birthYear;
int nbMatch = 0; input >> nbMatch;
for(int i = 0 ; i < nbMatch ; ++i) {
string match_date; input >> match_date;
p.matchDates.push_back(match_date);
}
return input;
}//*/
int main()
{
//ifstream pFile("players.txt");
int numberOfPlayers;
deque<Player> players;
cin >> numberOfPlayers; int i = 0;
while( i < numberOfPlayers)
{
Player p;
cin >> p;
players.push_back(p);
i++;
}
std::ostream_iterator< Player > output( cout, "\n" );
cout << "What we pushed into our deque: ";
copy( players.begin(), players.end(), output );
getchar();
return 0;
}
The Problem
This is the error Clang gives me:
error: invalid operands to binary expression ('istream' and 'string *')
Then it goes on to list the various overloads of operator>>() and why a right-hand operand of type std::string* cannot convert to respective right-hand types. This is expected because there are no overloads of operator>>() that take a pointer or array of that type.
Solution
When reading into an array, you normally read into "temporary" objects and copy that to the array. For example:
#include <iostream>
int main()
{
int array[5];
for (int i = 0, temp; i < 5 && std::cin >> temp; ++i)
{
array[i] = temp;
}
}
But in your case, you initialized your array with the following line which I assume to be an attempt to create an indefinitely-sized array:
matchDates = new string[];
I don't know about Visual Studio, but on Clang I got the following error:
Error(s):
error: expected expression
int* j = new int[];
^
1 error generated
Dynamically-sized arrays are not possible in C++. If you need an array that will grow in size, consider using a std::vector. You would need to call push_back() to insert elements.
You can put things at one line to ease the code for your eye but don't over do it. Take a 'record' as a one record, so you can say.
An array doesn't have the >> operator.
Would go for user 0x499602D2 his answer but I may not upvote nor comment yet, so I put it here as I already answered. ;)
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream pFile( "players.txt" );
int numberOfPlayers;
string firstName;
string lastName;
int birthYear;
int numberOfMatches = 0;
while( pFile >> numberOfPlayers )
{
for( int i = 0; i < numberOfPlayers; i++ )
{
pFile >> firstName >> lastName >> birthYear >> numberOfMatches;
cout << firstName << endl;
cout << lastName << endl;
cout << birthYear << endl;
for( int i = 0; i < numberOfMatches; i++ )
{
string date;
pFile >> date;
cout << date << endl;
}
}
}
getchar();
return 0;
}
To maintain the data you can createa a struct (or class). The second while loop is just to print out while the first gets the data.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
struct Player
{
string firstName;
string lastName;
int birthYear;
std::vector<string> matchDates;
};
int main()
{
ifstream pFile( "players.txt" );
int numberOfPlayers;
int numberOfMatches = 0;
std::vector<Player> players;
// fill the vector players
while( pFile >> numberOfPlayers )
{
for( int i = 0; i < numberOfPlayers; i++ )
{
// create player struct and fill it
Player player;
pFile >> player.firstName >> player.lastName >> player.birthYear >> numberOfMatches;
for( int i = 0; i < numberOfMatches; i++ )
{
string date;
pFile >> date;
player.matchDates.push_back( date );
}
// add it to the vector
players.push_back( player );
}
}
// print out the values
std::vector<Player>::iterator iterPlayer = players.begin(),
endPlayer = players.end;
while( iterPlayer != endPlayer )
{
Player player = *iterPlayer;
cout << player.firstName << endl;
cout << player.lastName << endl;
cout << player.birthYear << endl;
std::vector<string>::iterator iterDates = player.matchDates.begin(),
endDates = player.matchDates.end;
while( iterDates != endDates )
{
string date = *iterDates;
cout << date << endl;
}
}
getchar();
return 0;
}
I need coding for reading from File and store in differernt arrays !!!
for eg :
paul 23 54
john 32 56
My requirement are as follows: I need to store paul,john in string array and 23,32 in one integer array; and similarly 54,56 in another int array.
I read the inputs from the file and print it but I am unable to save in 3 different arrays.
int main()
{
string name;
int score;
ifstream inFile ;
inFile.open("try.txt");
while(getline(inFile,name))
{
cout<<name<<endl;
}
inFile.close();
}
So kindly suggest me some logics for doin this and I would really appreciate that... !!!
I assume you are new to programming? Or new to C++? So I provided the sample code to get you started. :)
#include <string>;
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<string> name;
vector<int> veca, vecb;
string n;
int a, b;
ifstream fin("try.txt");
while (fin >> n >> a >> b) {
name.push_back(n);
veca.push_back(a);
vecb.push_back(b);
cout << n << ' ' << a << ' ' << b << endl;
}
fin.close()
return 0;
}
You can try the following code:
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
int main()
{
std::string fileToRead = "file.log";
std::vector<int> column2, column3;
std::vector<std::string> names;
int number1, number2;
std::string strName;
std::fstream fileStream(fileToRead, std::ios::in);
while (fileStream>> strName >> number1 >> number2)
{
names.push_back(strName);
column2.push_back(number1);
column3.push_back(number2);
std::cout << "Value1=" << strName
<< "; Value2=" << number1
<< "; value2=" << number2
<< std::endl;
}
fileStream.close();
return 0;
}
The idea is to read the first column in file to a string (strName) and then push it to a vector (names). Similarly, second and third columns are read into number1 and number2 first and then pushed into vectors named column1 and column2, respectively.
Running it will get you the following results:
Value1=paul; Value2=23; value2=54
Value1=john; Value2=32; value2=56
I am trying to read the two words "kelly 1000" in the text file "players", into vectors players and balances respectively. Don't know why it's not working?
string name = "kelly";
int main()
{
int num =0;
vector<string> players;
vector<int> balances;
ifstream input_file("players.txt");
while(!input_file.eof())
{
input_file >> players[num];
input_file >> balances[num];
num++;
}
for(size_t i = 0; i=players.size(); i++)
{
if(name==players[i])
cout << "Welcome " << name << ", your current balance is " << balances[i] << "$." << endl;
else
break;
}
With operator[] you can only access existing elements. Going out of bounds invokes undefined behaviour. Your vectors are empty and you need to use push_back method to add elements to them.
Second problem is while (!file.eof()) anti-pattern. It'll typicaly loop one to many times because the read of last record doesn't neccesarily trigger eof. When reading from streams, always check whether input succeeded before you make use of values read. That's typicaly done by using operator>> inside loop condition.
string temp_s;
int temp_i;
while (input_file >> temp_s >> temp_i) {
players.push_back(temp_s);
balances.push_back(temp_i);
}
This way the loop stops if operator>> fails.
//Hope this is something you want dear.Enjoy
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
string name = "kelly";
int main()
{
int num =0;
string tempname;
int tempbalance;
vector<string> players;
vector<int> balances;
ifstream input_file("players.txt");
while(!input_file.eof())
{ input_file>>tempname;
input_file>>tempbalance;
players.push_back(tempname);
balances.push_back(tempbalance);
}
for(size_t i = 0; i<players.size(); i++)
{
if(name==players.at(i))
cout<< "Welcome " << name << ", your current balance is " << balances.at(i)<< "$." << endl;
}
return 0;
}