Reading Numbers from a File - c++

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.

Related

How to access data in a struct? 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?

How to use instream and ofstream to read and output a text file?

#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in ("input.txt");
ofstream out ("output.txt");
int main(){
char collection [30];
while ( in.good() ){
in >> collection;
}
cout << collection[0] <<endl;
in.close();
out.close();
return 0;
}
I'm trying to read a text file in C++ programming.But it certainly is not working since it doesn't print anything. It's just a single line containing some operands. Can someone help me out?
Put those definitions of in and out inside main. Don't create global variables unless you absolutely have to.
The code loops through the input, and overwrites the contents of collection each time through the loop. When it reaches the end of the input, it writes out the first character in collection. It should either display what it read each time through the loop, or add each string that it reads into a container. If it's the former, the code would look like this:
#include <fstream>
#include <iostream>
int main() {
std::ifstream in("input.txt");
std::string input;
while (in >> input)
std::cout << input << '\n';
return 0;
}
Note that the original code didn't use out, so I left it out here. Also, when in is an auto object (i.e., defined inside main), when main returns it gets destroyed. One of the things that the destructor does is close the file, so there is no need to call in.close();.
If you want to put the input into some kind of collection, that's a straightforward change:
#include <fstream>
#include <iostream>
#include <vector>
int main() {
std::ifstream in("input.txt");
std::string input;
std::vector<std::string> collection;
while (in >> input) {
collection.push_back(input);
std::cout << input << '\n';
}
std::cout << "Contents of collection:\n";
for (auto& x : collection)
std::cout << x << '\n';
return 0;
}
If you want to write the text to an output file, just do it:
#include <fstream>
int main() {
std::ifstream in("input.txt");
std::ofstream out("output.txt");
std::string input;
while (in >> input)
out << input << '\n';
return 0;
}
That will write each word from the input onto a separate line in the output file. If you just want to copy the file unchanged, that's even easier:
#include <fstream>
int main() {
std::ifstream in("input.txt");
std::ofstream out("output.txt");
out << in.rdbuf();
return 0;
}

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.

Copy file content to a string

I want to copy contents in a text file to a string or a *char. It would be better if I can copy the file content to an array of strings (each line an element of that array). This is my code:
int main() {
ifstream inFile;
inFile.open("index.in.txt"); //index.in has in each line a name and at the end there is a "."
char ab[11];
int q=0;
char *a[111];
if (inFile.is_open()) {
while (!inFile.eof()) {
inFile >> ab; //i think i don't understand this line correctly
a[q]=ab;
cout<<a[q]<<endl;
q++;
}
}
else{
cout<<"couldnt read file";
}
inFile.close();
cout<<"\n"<<ab<<endl; //it shoud be "." and it is
cout<<"\n"<<a[0]<<endl; //it should be "ion" but it gives me "."
return 0;
}
All values in the a array are equal to the last line which is dot
int main() {
ifstream inFile;
inFile.open("index.in.txt"); //index.in has in each line a name and at the end there is a "."
std::vector< std::string > lines;
std::string line;
if (inFile.is_open()) {
while ( getline( inFile, line ) ) {
lines.push_back( line );
}
}
...
now lines is a vector of string, each is a line from file
You are overwriting your only buffer everytime in inFile >> ab;
You read a line in buffer and save the address of buffer somewhere. Next time you read next line in the same buffer and save the exact same address as second line. If you read back your first line you will end up reading updated buffer i.e. last line.
You can change your code to
#include <vector>
#include <string>
#include <fstream>
using namespace std;
int main() {
ifstream inFile;
inFile.open("index.in.txt"); //index.in has in each line a name and at the end there is a "."
string ab; //char ab[11];
int q=0;
vector< string > a(111); //char *a[111];
if (inFile.is_open()) {
while (!inFile.eof()) {
inFile >> ab;
a[q]=ab;
cout<<a[q]<<endl;
q++;
}
}
else cout<<"couldnt read file";
inFile.close();
cout<<"\n"<<ab<<endl; //it shoud be "." and it is
cout<<"\n"<<a[0]<<endl; //it should be "ion" but it gives me "."
return 0;
}
Better use std::string and std::vector instead of arrays.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
bool ReadFile(const std::string &sFileName,
std::vector<std::string> &vLines)
{
std::ifstream ifs(sFileName);
if (!ifs)
return false;
std::string sLine;
while (std::getline(ifs, sLine))
vLines.push_back(sLine);
return !ifs.bad();
}
int main()
{
const std::string sFileName("Test.dat");
std::vector<std::string> vData;
if (ReadFile(sFileName, vData))
for (std::string &s : vData)
std::cout << s << std::endl;
return 0;
}
In order to read a line you MUST use std::getline. The >> operator will only read a word, that is a sequence of characters ended by a whitespace.
See: http://en.cppreference.com/w/cpp/string/basic_string/getline

Reading integers from an unorganized text file

#include <iostream>
#include <fstream>
#include <string>
#include <cctype> // isdigit();
using namespace std;
int main()
{
ifstream fin;
fin.open("Sayı.txt");
while (!fin.eof()){
string word;
int n;
fin >> word; //First i read it as a string.
if (isdigit(word[0])){ //checks whether is it an int or not
fin.unget(); //
fin >> n; // if its a int read it as an int
cout << n << endl;
}
}
}
Suppose the text file is something like this:
100200300 Glass
Oven 400500601
My aim is simply to read integers from that text file and show them in console.
So the output should be like
100200300
400500601
You can see my attempt above.As output i get only the last digit of integers.Here's a sample output:
0
1
Simple just try converting the string read to an int using string streams, if it fails then it isn't an integer , otherwise it is an integer.
ifstream fin;
istringstream iss;
fin.open("Say1.txt");
string word;
while (fin>>word )
{
int n=NULL;
iss.str(word);
iss>>n;
if (!iss.fail())
cout<<n<<endl;
iss.clear();
}
I think the following should do what you want (untested code):
int c;
while ((fin >> std::ws, c = fin.peek()) != EOF)
{
if (is_digit(c))
{
int n;
fin >> n;
std::cout << n << std::endl;
}
else
{
std::string s;
fin >> s;
}
}