How to access data in a struct? C++ - c++

Just quick one, how should I go about printing a value from a struct? the 'winningnums' contains a string from another function (edited down for minimal example)
I've tried the below but the program doesnt output anything at all, is my syntax incorrect?
struct past_results {
std::string date;
std::string winningnums;
};
int main(){
past_results results;
std::cout << results.winningnums;
return 0;
}
EDIT:
just to give some more insight, here's the function that populates my struct members. Is it something here im doing wrong?
//function to read csv
void csv_reader(){
std::string line;
past_results results;
past_results res[104];
int linenum = 0;
//open csv file for reading
std::ifstream file("Hi S.O!/path/to/csv", std::ios::in);
if(file.is_open())
{
while (getline(file, line))
{
std::istringstream linestream(line);
std::string item, item1;
//gets up to first comma
getline(linestream, item, ',');
results.date = item;
//convert to a string stream and put into winningnums
getline(linestream, item1);
results.winningnums = item1;
//add data to struct
res[linenum] = results;
linenum++;
}
}
//display data from struct
for(int i = 0; i < linenum; i++) {
std::cout << "Date: " << res[i].date << " \\\\ Winning numbers: " << res[i].winningnums << std::endl;
}
}

is my syntax incorrect?
No, it's just fine and if you add the inclusion of the necessary header files
#include <iostream>
#include <string>
then your whole program is ok and will print the value of the default constructed std::string winningnums in the results instance of past_results. A default constructed std::string is empty, so your program will not produce any output.
Your edited question shows another problem. You never call csv_reader() and even if you did, the result would not be visible in main() since all the variables in csv_reader() are local. Given a file with the content:
today,123
tomorrow,456
and if you call csv_reader() from main(), it would produce the output:
Date: today \\ Winning numbers: 123
Date: tomorrow \\ Winning numbers: 456
but as I mentioned, this would not be available in main().
Here's an example of how you could read from the file and make the result available in main(). I've used a std::vector to store all the past_results in. It's very practical since it grows dynamically, so you don't have to declare a fixed size array.
#include <fstream>
#include <iostream>
#include <sstream> // istringstream
#include <string> // string
#include <utility> // move
#include <vector> // vector
struct past_results {
std::string date;
std::string winningnums;
};
// added operator to read one `past_results` from any istream
std::istream& operator>>(std::istream& is, past_results& pr) {
std::string line;
if(std::getline(is, line)) {
std::istringstream linestream(line);
if(!(std::getline(linestream, pr.date, ',') &&
std::getline(linestream, pr.winningnums)))
{ // if reading both fields failed, set the failbit on the stream
is.setstate(std::ios::failbit);
}
}
return is;
}
std::vector<past_results> csv_reader() { // not `void` but returns the result
std::vector<past_results> result; // to store all past_results read in
// open csv file for reading
std::ifstream file("csv"); // std::ios::in is default for an ifstream
if(file) {
// loop and read records from the file until that fails:
past_results tmp;
while(file >> tmp) { // this uses the `operator>>` we added above
// and save them in the `result` vector:
result.push_back(std::move(tmp));
}
}
return result; // return the vector with all the records in
}
int main() {
// get the result from the function:
std::vector<past_results> results = csv_reader();
// display data from all the structs
for(past_results& pr : results) {
std::cout << "Date: " << pr.date
<< " \\\\ Winning numbers: " << pr.winningnums << '\n';
}
}

Your example doesn't initialize the struct members. There is no data to print, so why would you expect it to output anything?

Related

Reading and storing every second line

I am creating a small search engine to find values in files and store them. I have a txt file with the data:
link1
cat, dog, bird
link2
car, wheel, chair
There is a code to read and store, but the index map is empty.
int function(string filename, map<string, set<string>>& index) {
int counter = 0;
set <string> tokens;
ifstream inStream;
inStream.open(filename);
if (inStream.fail()){
counter = 0;
}
string http, definition;
while (getline(inStream, http) && getline(inStream, definition)){
for (auto v : tokens){
index[v].insert(http);
counter++
}
}
return counter;
}
You forgot to split the items in each second line.
This is basically very simple.
You can use the well known std::getline with delimiter concept.
The corrected version of your code will be:
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <set>
std::istringstream fileSimulationStream{R"(link1
cat, dog, bird
link2
car, wheel, chair)"};
int main() {
// Resulting data
std::map<std::string, std::set<std::string>> data;
// Read all lines from file. always 2 lines in one shot
for (std::string link{}, item{}; std::getline(fileSimulationStream, link) and std::getline(fileSimulationStream, item); ) {
// Put line in an istringstream for further extraction
std::istringstream iss{item};
// Read the items
std::set<std::string> tempSet{}; std::string tempString{};
while (std::getline(iss, tempString, ',')) tempSet.insert(tempString);
// Now add everything to the map
data[link] = std::move(tempSet);
}
// Create some debug output
for (const auto&[key, set] : data) {
std::cout << key << "\t--> ";
for (const std::string s : set) std::cout << s << ' ';
std::cout << '\n';
}
}

How do I include an int inside a getline();

Just a simple question, how do I include int values inside a getline()? I have searched online but couldn't find any that helps me. I am reading off a txt file. It is a row of numbers. For eg: 1,2,3,4,5. I am hoping that I can apply these int values anywhere so that the only way I can change the values is through the txt file.
I decided to use getline() but realise that I cannot use an integer. I am sorry, I am new to this C++. I hope that you can tell me where I went wrong.
Thanks!
This is my struct:
struct vacancyData {
int CCSpot;
int SNSpot;
int TPSpot;
int SCSpot;
int DRSpot;
};
This is my code:
ifstream File2;
File2.open("Vacancy.txt");
vector<vacancyData> v1;
vacancyData f;
while (getline(File2, f.CCSpot, ','))
{
getline(File2, f.SNSpot, ',');
getline(File2, f.TPSpot, ',');
getline(File2, f.SCSpot, ',');
getline(File2, f.DRSpot, '\n');
v1.push_back(f);
}
The direct answer to the question
How do I include an int inside a getline()
is: This is not possible at all.
std::getline is basically used to read a std::string from a stream, until a delimiter is found. In most cases, and that is also a default argument, the delimiter is '\n'. And with that, a complete line is read into a std::string. Please read here for a description.
If your input data is OK in most cases, then no std::getline is needed. Basic input validation can also be done directly. Please see the below example code:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
struct VacancyData {
int CCSpot;
int SNSpot;
int TPSpot;
int SCSpot;
int DRSpot;
};
int main() {
// Filename
const std::string fileName{ "r:\\vacancy.txt" };
// Open file and check, if it could be opened. Use C++17 if-statement with initializer
if (std::ifstream vacancyFileStream{ fileName }; vacancyFileStream) {
// Here we will stor our data
std::vector<VacancyData> all{};
// Temps, to check, if delimiter is comma
char c1{}, c2{}, c3{}, c4{};
// This is one for loop and will read the complet file and do basic input validation
for (VacancyData vc{};
(vacancyFileStream >> vc.CCSpot >> c1 >> vc.SNSpot >> c2 >> vc.TPSpot >> c3 >> vc.SCSpot >> c4 >> vc.DRSpot) &&
c1 == ',' && c2 == ',' && c3 == ',' && c4 == ',';
all.push_back(vc))
; // Empt loop body. No statement within for loop body
// Ws there an error and could all data be read?
if (vacancyFileStream.fail() || not vacancyFileStream.eof())
std::cerr << "\n\nErorw hile reading input data\n\n";
for (const VacancyData& vc : all)
std::cout << vc.CCSpot << '\t' << vc.SNSpot << '\t' << vc.TPSpot << '\t' << vc.SCSpot << '\t' << vc.DRSpot << '\n';
}
else std::cerr << "\n\nEror: cannot open source file '" << fileName << "'\n\n";
return 0;
}
But, it is considere good practice to first read a complete line, then split it up in parts and then convert it to your structure elements.
Additionally: In C++ we often use an object oriented approach. Meaning, and objects methods, operating with the data are encapsulated in a class/struct.
In your case, we would overwrite the extractor >> and inserter operator <<.
This would then look like that (I am using C++17):
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
struct VacancyData {
int CCSpot;
int SNSpot;
int TPSpot;
int SCSpot;
int DRSpot;
friend std::istream& operator >> (std::istream& is, VacancyData& vc) {
char c{};
return is >> vc.CCSpot >> c >> vc.SNSpot >> c >> vc.TPSpot >> c >> vc.SCSpot >> c >> vc.DRSpot;
}
friend std::ostream& operator << (std::ostream& os, const VacancyData& vc) {
return os << vc.CCSpot << '\t' << vc.SNSpot << '\t' << vc.TPSpot << '\t' << vc.SCSpot << '\t' << vc.DRSpot;
}
};
int main() {
// Filename
const std::string fileName{ "r:\\vacancy.txt" };
// Open file and check, if it could be opened. Use C++17 if-statement with initializer
if (std::ifstream vacancyFileStream{ fileName }; vacancyFileStream) {
// Here we will store our data. Read complete file and parse it
std::vector all(std::istream_iterator< VacancyData>(vacancyFileStream), {});
// Ws there an error and could all data be read?
if (vacancyFileStream.fail() || not vacancyFileStream.eof())
std::cerr << "\n\nErorw hile reading input data\n\n";
// Show output
for (const VacancyData& vc : all)
std::cout << vc << '\n';
}
else std::cerr << "\n\nEror: cannot open source file '" << fileName << "'\n\n";
return 0;
}
Now, if you want to change the reading of your data, you can use any method that you want. For example, you can read a complete line, using std::getline use any method shown below to split the input string into parts. Then you can use any method to convert that string parts into an integer for your struct. You will just change the body of your extractor operator. Nothing else will be affected. That sis the beauty of encapsulation.
Regarding: Splitting a string into tokens is a very old task. There are many many solutions available. All have different properties. Some are difficult to understand, some are hard to develop, some are more complex, slower or faster or more flexible or not.
Alternatives
Handcrafted, many variants, using pointers or iterators, maybe hard to develop and error prone.
Using old style std::strtok function. Maybe unsafe. Maybe should not be used any longer
std::getline. Most used implementation. But actually a "misuse" and not so flexible
Using dedicated modern function, specifically developed for this purpose, most flexible and good fitting into the STL environment and algortithm landscape. But slower.
Please see 4 examples in one piece of code.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <forward_list>
#include <deque>
using Container = std::vector<std::string>;
std::regex delimiter{ "," };
int main() {
// Some function to print the contents of an STL container
auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),
std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << '\n'; };
// Example 1: Handcrafted -------------------------------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c{};
// Search for comma, then take the part and add to the result
for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {
// So, if there is a comma or the end of the string
if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {
// Copy substring
c.push_back(stringToSplit.substr(startpos, i - startpos));
startpos = i + 1;
}
}
print(c);
}
// Example 2: Using very old strtok function ----------------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c{};
// Split string into parts in a simple for loop
#pragma warning(suppress : 4996)
for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {
c.push_back(token);
}
print(c);
}
// Example 3: Very often used std::getline with additional istringstream ------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c{};
// Put string in an std::istringstream
std::istringstream iss{ stringToSplit };
// Extract string parts in simple for loop
for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))
;
print(c);
}
// Example 4: Most flexible iterator solution ------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
//
// Everything done already with range constructor. No additional code needed.
//
print(c);
// Works also with other containers in the same way
std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
print(c2);
// And works with algorithms
std::deque<std::string> c3{};
std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));
print(c3);
}
return 0;
}
In modern C++ you would probably do:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
#include <regex>
// Regex for integer
const std::regex re{R"(([-+]?\d+))"};
struct VacancyData {
int CCSpot;
int SNSpot;
int TPSpot;
int SCSpot;
int DRSpot;
friend std::istream& operator >> (std::istream& is, VacancyData& vc) {
// Read a complete line and check, if that worked
if (std::string line{}; std::getline(is, line)) {
// Split the string into parts. The parts will definitely contain a integer
std::vector part(std::sregex_token_iterator(line.begin(), line.end(), re), {});
// Sanity check. Could we read 5 values?
if (not (part.size() == 5u)) {
std::cerr << "\n\nError while parsing line '" << line << '\n';
is.setstate(std::ios::failbit);
}
else {
// Splitting the string worked. We will have intergers in the parts. stoi will not fail
vc.CCSpot = std::stoi(part[0]);
vc.SNSpot = std::stoi(part[1]);
vc.TPSpot = std::stoi(part[2]);
vc.SCSpot = std::stoi(part[3]);
vc.DRSpot = std::stoi(part[4]);
}
}
return is;
}
friend std::ostream& operator << (std::ostream& os, const VacancyData& vc) {
return os << vc.CCSpot << '\t' << vc.SNSpot << '\t' << vc.TPSpot << '\t' << vc.SCSpot << '\t' << vc.DRSpot;
}
};
int main() {
// Filename
const std::string fileName{ "r:\\vacancy.txt" };
// Open file and check, if it could be opened. Use C++17 if-statement with initializer
if (std::ifstream vacancyFileStream{ fileName }; vacancyFileStream) {
// Here we will store our data. Read complete file and parse it
std::vector all(std::istream_iterator< VacancyData>(vacancyFileStream), {});
// Show output
for (const VacancyData& vc : all)
std::cout << vc << '\n';
}
else std::cerr << "\n\nEror: cannot open source file '" << fileName << "'\n\n";
return 0;
}
But, there are tons of different possible solutions. And everybody can select whatever.
All above needs to be compiles with C++17.
You can use std::getline to do this, but you need use a std::string and then to convert it to an integer. One way is to use the std::stoi function.
Example:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
struct vacancyData {
int CCSpot;
int SNSpot;
int TPSpot;
int SCSpot;
int DRSpot;
};
// Overload operator>> for reading a "vacancyData" struct from an istream (like a file)
std::istream& operator>>(std::istream& is, vacancyData& vd) {
std::string tmp;
try {
if(std::getline(is, tmp, ',')) {
vd.CCSpot = std::stoi(tmp);
if(std::getline(is, tmp, ',')) {
vd.SNSpot = std::stoi(tmp);
if(std::getline(is, tmp, ',')) {
vd.TPSpot = std::stoi(tmp);
if(std::getline(is, tmp, ',')) {
vd.SNSpot = std::stoi(tmp);
if(std::getline(is, tmp, ',')) {
vd.SCSpot = std::stoi(tmp);
if(std::getline(is, tmp)) {
vd.DRSpot = std::stoi(tmp);
}
}
}
}
}
}
}
catch(...) { // one of the stoi calls failed
is.setstate(std::ios::failbit);
}
return is;
}
int main() {
std::ifstream File2("Vacancy.txt");
if(File2) {
// construct the vector using iterators:
std::vector<vacancyData> v1(std::istream_iterator<vacancyData>(File2),
std::istream_iterator<vacancyData>{});
// use the filled vector "v1" ...
}
}
But since there is built-in support for extracting ints directly from istreams, I suggest using that instead.
Example:
// A small support class to "eat" separators, like comma and newline
struct eater { char ch; };
std::istream& operator>>(std::istream& is, eater& e) {
if(is.peek() == e.ch) is.ignore(); // if the next char is the expected, skip it
else is.setstate(std::ios::failbit); // else set the failbit
return is;
}
std::istream& operator>>(std::istream& is, vacancyData& vd) {
eater comma{','};
eater newline{'\n'};
return is >>
vd.CCSpot >> comma >>
vd.SNSpot >> comma >>
vd.TPSpot >> comma >>
vd.SCSpot >> comma >>
vd.DRSpot >> newline;
}

Reading Triangle Data Mesh With Object Files

I need to load in the vertices of a .obj file in c++. I just copied over the verts from the object I downloaded so I didn't have to worry about texture mapping or anything. I was able to separate it into a single line and get rid of the v but am not able to isolate the x,y,z coordinates so I can assign it to three separate variables.
main.cpp
// ConsoleApplication3.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <memory>
#include <fstream>
#include <string>
using namespace std;
string pos1, pos2, pos3;
int main()
{
string line;
ifstream myfile("fox.txt");
if (myfile.is_open())
{
while (getline(myfile, line))
{
line.erase(std::remove(line.begin(), line.end(), 'v'), line.end());
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
fox.txt
v 10.693913 60.403057 33.765018
v -7.016389 46.160694 36.028797
v 9.998714 51.307644 35.496368
v -8.642366 49.095310 35.725204
A simple way to read in the line
v 10.693913 60.403057 33.765018
and separate it into 3 different variables is to first read in a char, then read in three doubles:
ifstream fin("fox.txt");
vector <vector<double>> data; // holds sets of coordinates
double a, b, c;
char v;
while(fin >> v >> a >> b >> c){
data.push_back({a, b, c});
}
If you wanted, you could also use std::stringstream to parse the input into doubles.
An easy way is to simply use std::stringstream and treat it like you would any other stream.
#include <sstream>
...
std::string pos1, pos2, pos3;
std::stringstream lineStream;
...
while (getline(myfile, line))
{
/* Make a string stream out of the line we read */
lineStream.str(line);
char skip; // Temp var to skip the first 'v'
lineStream >> skip >> pos1 >> pos2 >> pos3;
/* Reset error state flags for next iteration */
lineStream.clear();
}
Or you could avoid all that by using the >> operator on myfile directly.
std::string temp, pos1, pos2, pos3;
while (myfile >> temp >> pos1 >> pos2 >> pos3)
{
...
}
I'm going to figure you want to store this data in the likes of a std::vector. This is one way of doing it.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
const char* test_str = R"(
v 10.693913 60.403057 33.765018
v -7.016389 46.160694 36.028797
v 9.998714 51.307644 35.496368
v -8.642366 49.095310 35.725204
)";
struct data_item {
double x;
double y;
double z;
};
using data_set = std::vector<data_item>;
int main()
{
//std::ifstream myfile("fox.txt");
//if (!myfile.is_open()) {
// std::cout << "Unable to open file\n";
// return -1;
//}
std::stringstream as_file;
as_file << test_str;
data_set set;
for (; ;) {
std::string dummy;
data_item item;
as_file >> dummy >> item.x >> item.y >> item.z;
if (!dummy.size())
break;
set.push_back(item);
}
for (auto& item : set)
std::cout << item.x << " " << item.y << " " << item.z << std::endl;
return 0;
}
Don't do: using namespace std; It will save you a lot of headaches down the road. It also makes your code more readable to know stuff is out of the standard library.
When testing, it is sometimes more simple to use local data as I have with test_str. As pointed out in the comments, you could just let the stream do the conversion from text to doubles.
Note I've taken care of a failed file error in one place, the commented file stuff. Putting an else way down from the failure is not so clear and creates a large unneeded scope.

Unable to read text file with boolean grid into vectors of vectors

I have a text file which consists of boolean grid like structure as shown. Now, I am trying to read the text file into a vector<vector<bool>> grid. But I am unable to do so. My code is exiting without any error and execution is not moving inside the while loop.
Text file has below sample:
00000000000000001111111110000
000000100000000010100000100
0000000000000000111111111000
00000000000000011111111111000
0001000000000011111111111110
00000000000000011000000011000
00000000000000100010001000100
00000000000000100000100000
00100011111111111111111001110
00000000000011111000100000001
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
vector<vector<bool> >read_grid(const string &filename)
{
vector<vector<bool> > gridvector;
// Open the File
ifstream in(filename.c_str());
string str;
bool tempb;// Check if object is valid
if(!in)
{
cout<< "Cannot open the File : "<<filename<<endl;
return gridvector;
}
// Read the next line from File untill it reaches the end.
while (getline(in, str))
{
istringstream iss(str);
vector<bool> myvector;
while(iss>>tempb)
{
myvector.push_back(tempb);
}
gridvector.push_back(myvector);
}
//Close The File
in.close();
return gridvector;
}
void display_grid(vector< vector<bool> >& grid)
{
// this generates an 8 x 10 grid and sets all cells to ’0’
//vector<vector<bool> >grid(8, vector<bool>(10, 1));// printing the grid
for(int x = 0; x < grid.size(); x++)
{
for(int y = 0;y < grid[x].size();y++)
{
// cout<<grid[x].size()<<'\n';
cout << grid[x][y];
}
cout << endl;
}
cout<<"grid at position [1][2] is: "<< grid[1][2]<<'\n';
}
int main ()
{
const string b_file = "intial_grid.txt";
vector< vector<bool> > grid_copy = read_grid(b_file);
display_grid(grid_copy);
return 0;
}
It is exiting with 'exit status -1'.
String stream returns true on successful read and false on error.
In your case, iss >> tempb will fail as it is expecting a boolean value, i.e, a bit, but instead receives a string of 0s and 1s.
You can check this after first read iss >> tempb,
if (iss.fail()) {
cout << "Failed to read\n";
}
You could instead iterate over the characters individually.
// Read the next line from File untill it reaches the end.
while (getline(in, str))
{
istringstream iss(str);
vector<bool> myvector;
char bit;
while(iss >> bit)
{
myvector.push_back(bit == '1' ? true : false);
}
gridvector.push_back(myvector);
}
The answer is given and accepted. The errors have been mentioned in the comments.
Anyway, I would like to show a "more" C++ approach, using std algorithms.
The idea is that we want to read a line with boolean values. So I designed a new data type, a class, that contains such data and also knows how to read it. In my humble opinion, the data and the methods should be packed in a class.
This will also reduce the lines of code in function main and overall drastically. In the definition of the variable and through the range constructor, all data will be read.
I added additional some debug output, so that the result can be visualized. Of course the access of the data using the index operator [][] will also work.
Please see:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>
std::istringstream testData(
R"#(00000000000000001111111110000
000000100000000010100000100
0000000000000000111111111000
00000000000000011111111111000
0001000000000011111111111110
00000000000000011000000011000
00000000000000100010001000100
00000000000000100000100000
00100011111111111111111001110
00000000000011111000100000001
)#");
// We want to have a data type for one line with boolean values in a string
struct Line {
// We overwrite the extractor operator >> . With that we can easily read a complete line
friend std::istream& operator >> (std::istream& is, Line& l) {
std::string line{}; l.lineOfBool.clear(); getline(is, line);
std::transform(line.begin(), line.end(), std::back_inserter(l.lineOfBool), [](const char c) { return (c == '1') ? true : false; });
return is; }
// Type cast operator to expected value
operator std::vector<bool>() const { return lineOfBool; }
// The data
std::vector<bool> lineOfBool{};
};
int main()
{
// Define the variable that will hold all bool data of the complete file. The range constructor will read the file
std::vector<std::vector<bool>> fileAsStrings{std::istream_iterator<Line>(testData),std::istream_iterator<Line>() };
// For debug purposes: Copy all Data to std::cout
std::for_each(fileAsStrings.begin(), fileAsStrings.end(), [](const std::vector<bool> & l) {std::copy(l.begin(), l.end(), std::ostream_iterator<bool>(std::cout, " ")); std::cout << '\n'; });
return 0;
}
Please note: I do read from an istringstream, initilized with a raw string. So, no difference to reading from a file.
Maybe somebody finds this solution helpful.
The error 'exit status -1' is caused to display_grid() function, the components are vector and the access to the vector is verctorVariable.at();
another error is while(iss>>tempb) because your result is all row, your resolve this problem with this code
istringstream iss(str);
vector<bool> myvector;
string value;
iss >> value;
cout << value;
for(char c : value){
cout << "**** debug print: " << c << endl;
myvector.push_back((bool)(c-'0'));
}
gridvector.push_back(myvector);
also, your method display_grid() should be this
void display_grid(vector< vector<bool> >& grid)
{
// this generates an 8 x 10 grid and sets all cells to ’0’
//vector<vector<bool> >grid(8, vector<bool>(10, 1));// printing the grid
for(int x = 0; x < grid.size(); x++)
{
cout<<"addin another elemen";
for(int y = 0;y < grid[x].size();y++)
{
cout<<"addin another elemen";
cout << grid.at(x).at(y);
}
cout << endl;
}
//cout<<"grid at position [1][2] is: "<< grid[1][2]<<'\n';
}
This code return this exit code Process finished with exit code 0

Reading Numbers from a File

I have a file with many numbers. The file looks like "192 158 100 0 20 200" basically like that. How can I load the files number values 1 at a time and display them on the screen in C++?
try something like this:
int val;
std::ifstream file("file");
while (file >> val)
std::cout << val;
The following program should print each number, one per line:
#include <iostream>
#include <fstream>
int main (int argc, char *argv[]) {
std::ifstream ifs(argv[1]);
int number;
while (ifs >> number) {
std::cout << number << std::endl;
}
}
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
int main() {
std::ifstream fs("yourfile.txt");
if (!fs.is_open()) {
return -1;
}
// collect values
// std::vector<int> values;
// while (!fs.eof()) {
// int v;
// fs >> v;
// values.push_back(v);
// }
int v;
std::vector<int> values;
while (fs >> v) {
values.push_back(v);
}
fs.close();
// print it
std::copy(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}
Please consider the following code:
ifstream myReadFile;
myReadFile.open("text.txt");
int output;
if (myReadFile.is_open())
{
while (fs >> output) {
cout<<output;
}
}
//Of course closing the file at the end.
myReadFile.close();
As well, please include the iostream and fstream inside your code when using the example above.
Note that you need to start open a filestream to read and you can try to read it char by char and detect is there any white space in between it.
Good luck.
Another way of doing it:
std::string filename = "yourfilename";
//If I remember well, in C++11 you don't need the
//conversion to C-style (char[]) string.
std::ifstream ifs( filename.c_str() );
//Can be replaced by ifs.good(). See below.
if( ifs ) {
int value;
//Read first before the loop so the value isn't processed
//without being initialized if the file is empty.
ifs >> value;
//Can be replaced by while( ifs) but it's not obvious to everyone
//that an std::istream is implicitly cast to a boolean.
while( ifs.good() ) {
std::cout << value << std::endl;
ifs >> value;
}
ifs.close();
} else {
//The file couldn't be opened.
}
The error-handling can be done in many ways through.