How to read txt file into vector and cout the file? - c++

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<int> temp;
ifstream infile;
infile.open("numbers");
if (infile.fail())
{
cout << "Could not open file numbers." << "\n";
return 1;
}
int data;
infile >> data;
while (!infile.eof()) {
temp.push_back(data);
infile >> data;
}
cout << data << " " << endl;
}
I am simply trying to cout all the numbers from the text file "numbers" using a vector.
15
10
32
24
50
60
25
My experience is pretty much nil, and some guidance on why this fails to open would be very helpful.

Your code isn't working because you haven't attempted to print anything from the vector?
How do I print a vector?
Well first you have to understand how not to print a vector. The last line in your code, particularly this one:
cout << data << " " << endl;
is only printing out the last integer from the text file. In the loop where you performed the input, infile >> data overwrote each previous value of data and assigned it to the currently read value from the file. The result is that when the loop finishes, data will be equal to the last read value, particularly 25 looking at your file.
There's no overload for operator<<() that will allow you to do something like cout << temp, though you can implement one yourself. There exist several ways to print a vector, the easiest being a simple loop:
for (unsigned i = 0; i < temp.size(); ++i)
std::cout << temp[i] << " ";
Bonus: A faster way to print all the integers would be to print data from inside the loop. There's also the answer #KerrekSB made.

Your code is fine but you're printing the wrong thing.
Change the bottom of main to this
int data;
while (infile >> data) {
temp.push_back(data);
}
for( vector<int>::iterator i = temp.begin(); i != temp.end(); i++) {
cout << *i << endl;
}
*Edited after reading the suggested dup.

Try this:
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
std::ifstream infile("data.txt");
if (!infile) { /* error opening file */ }
for (int n : std::vector<int>(std::istream_iterator<int>(infile), {}))
{
std::cout << n << '\n';
}
}
Of course you don't need the vector if you just want to process the numbers:
for (std::istream_iterator<int> it(infile), end; it != end; ++it)
{
std::cout << *it << '\n';
}

Related

Issue printing .txt file in program C++

I have a program that takes a text file and list the words and how many times they are used. It works but I can't figure out how to print out the text file. Above the sorted words and how many times they appear, I want to display the text from the file. How would I do that? I tried several things but it either does nothing or screws up the rest of the code saying there are 0 unique words. And lastly how would print out the results so they are more ... table -ish...
/*
Something like this:
Word: [equal spaces] Count:
ask [equal spaces] 5
anger [equal spaces] 3
*/
Thank you for any assistance you can provide me.
#include <iterator>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <cctype>
using namespace std;
string getNextToken(istream &in) {
char c;
string ans="";
c=in.get();
while(!isalpha(c) && !in.eof())//cleaning non letter charachters
{
c=in.get();
}
while(isalpha(c))
{
ans.push_back(tolower(c));
c=in.get();
}
return ans;
}
string ask(string msg) {
string ans;
cout << msg;
getline(cin, ans);
return ans;
}
int main() {
map<string,int> words;
ifstream fin( ask("Enter file name: ").c_str() ); //open an input stream
if( fin.fail() ) {
cerr << "An error occurred trying to open a stream to the file!\n";
return 1;
}
string s;
string empty ="";
while((s=getNextToken(fin))!=empty )
++words[s];
while(fin.good())
cout << (char)fin.get(); // I am not sure where to put this. Or if it is correct
cout << "" << endl;
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "----------------------------------------------------------------" << endl;
cout << " " << endl;
for(map<string,int>::iterator iter = words.begin(); iter!=words.end(); ++iter)
cout<<iter->first<<' '<<iter->second<<endl;
return 0;
}
I would just use a simple for loop like this:
for (int x = 0; x < words.size(); x++){
cout >> words[x] << endl
}
And then modify from there to get your desired format.
I did notice though, that you are not returning a value for main in all paths of the above code, which should give a compile time error, but did not when I compiled it, for some reason. I would remind you that you need to have a return value for main. Unless I am misunderstanding your question. I could not run this program without creating a sample file, and so could not test it without extra work. But the program did compile. I did not expect to, because of the missing return statement. If you can make this reproduce your error without me having to create a sample file of words, ei insert the list of words into the code and minimally reproduce the error, I would be able to help you better. As it is, I hope that I helped you.
Something like this should make it:
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <string>
int main( int argc, char* argv[] )
{
std::string file;
std::cout << "Enter file name: ";
std::cin >> file;
std::fstream in( file.c_str() );
if ( in.good() )
{
std::unordered_map<std::string, int> words;
std::string word;
//Use this to separate your words it could be '\n' or anything else
char cSeparator = ' ';
while ( in >> word )
{
//Print the word
std::cout << word << cSeparator;
++words[word];
}
std::cout << std::endl;
//Headers Word and Count separated by 2 tabs
std::cout << "Word:\t\tCount:" << std::endl;
for ( auto& w : words )
std::cout << w.first << "\t\t" << w.second << std::endl;
}
in.close();
return EXIT_SUCCESS;
}
However this is assuming that the text file only contains the words, if you have other kind of stuff there, you should be able to filter it as you want.

printing weird symbols to output file, c++

I am writing a code that reads an input file of numbers, sorts them in ascending order, and prints them to output. The only thing printed to output is some really freaky symbols.
Here is my code
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
int i, y, temp, num[20];
char file_nameI[21], file_nameO[21];
ofstream outfile;
ifstream infile;
cout << "Please enter name of input file: ";
cin >> file_nameI;
infile.open(file_nameI);
if (!infile)
{
cout << "Could not open input file \n";
return 0;
}
cout << "Please enter name of output file: ";
cin >> file_nameO;
outfile.open(file_nameO);
if (!outfile)
{
cout << "Could not open output file \n";
return 0;
}
for (i = 0; i < 20; i++)
{
y = i + 1;
while (y < 5)
{
if (num[i] > num[y]) //Correction3
{
infile >> temp;
temp = num[i];
num[i] = num[y];
num[y] = temp;
//y++; //Correction4
}
y++;
}
}
for (i = 0; i < 5; i++)
outfile << "num[i]:" << num[i] << "\n";
return 0;
}
Here is my input
6 7 9 0 40
Here is the output
 „Ô,üþ 54
H|À°ÀzY „Ô,üþ 0
Problems with your code are already mentioned in the comments but again:
First problem is uninitialized elements of num[20] - elements of num have indeterminate values so accessing any of them triggers undefined behavior. You should first read them from the file or at least initialize them to some default value.
The part of code that should most likely do the sorting is just completely wrong. If you'd like to implement your own function for sorting, you can pick up some well-known algorithm like e.g. quicksort - but C++ Standard Library already provides sorting function - std::sort.
Besides obvious mistakes:
You are using char[] - in C++ it's almost always better to use std::string.
Your static array can only store 20 values and you are reading those from a file. You can use std::vector which can grow when you add more elements than its current capacity. It also automatically fixes the problem with uninitialized elements of num[20].
As mentioned in the comments you can organize your code and improve readability by splitting it into functions.
Here you've got it quickly rewritten. This code uses std::string instead of char[], std::vector to store the numbers and std::sort. If there is something you don't understand here, read SO documentation:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> read_file(ifstream& in_file)
{
vector<int> vec;
int value;
while (in_file >> value)
{
vec.push_back(value);
}
return vec;
}
void write_file(ofstream& out_file, const vector<int>& values)
{
for (size_t i = 0; i < values.size(); ++i)
out_file << "value #" << i << ": " << values[i] << '\n';
}
int main()
{
string input_filename, output_filename;
ofstream out_file;
ifstream in_file;
cout << "Please enter name of input file: ";
cin >> input_filename;
in_file.open(input_filename);
if (!in_file)
{
cout << "Could not open input file\n";
return 0;
}
cout << "Please enter name of output file: ";
cin >> output_filename;
out_file.open(output_filename);
if (!out_file)
{
cout << "Could not open output file\n";
return 0;
}
auto numbers = read_file(in_file);
sort(begin(numbers), end(numbers));
write_file(out_file, numbers);
return 0;
}
You might forgot to store values in num array. Just update your code as follows and it will work.
infile.open(file_nameI);
if (!infile){
cout << "Could not open input file \n";
return 0;
} else{
i = 0;
while (infile >> num[i]){
i++;
}
}

Input elements differ from output elements from files C++

I have been having some problems with my code. I was asked to input elements from an .dat file into an array. For class we have to do this for various files without knowing how many elements will be in each file. The only thing we know is that here will never be more then 5000 elements per file.
One of my input file has the following elements:
5.675207 -0.571210
0.728926 0.666069
2.290909 0.751731 2.004545 0.907396
0.702893 0.646427 5.909504 -0.365045
2.082645 0.871841 5.597107 -0.633507
6.117769 -0.164663 6.091736 -0.190282
5.571074 -0.653433 4.503719 -0.978307
3.983058 -0.745620
3.670661 -0.504729
5.857438 -0.413001
When I run my code:
#define _CRT_NONSTDC_NO_DEPRECATE
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main(int argc, char * argv[])
{
ifstream fin;
ofstream fout;
if (argc < 3)
{
cout << "Incorrect usage: prog.exe filenname number" << endl;
cout << "Exiting now, please try again." << endl;
return -1;
}
fin.open(argv[1]);
if (!fin)
{
cout << "Error opening file \"" << argv[1] << "\", exiting." << endl;
return -1;
}
fout.open(argv[2]);
int count = 0;
int word;
double points[5000];
while (fin >> word)
{
fin >> points[count];
++count;
}
fout << "Numer of points is: " << count/2 << endl;
for (int i = 0; i < count; i++)
{
fout << points[i] << " ";
}
fin.close();
fout.close();
return 0;
}
I outputted the elements just to make sure that they were properly inputted. I get the following and I don't know why.
0.675207 0.57121
0.728926 0.666069
0.290909 0.751731 0.004545 0.907396
0.702893 0.646427 0.909504 0.365045
0.082645 0.871841 0.597107 0.633507
0.117769 0.164663 0.091736 0.190282
0.571074 0.653433 0.503719 0.978307
0.983058 0.74562
0.670661 0.504729
0.857438 0.413001
The first digit is converted to a 0 for some reason and the negative ones become positive. Would anyone know why this is occurring?
int word;
is doing you no favours. First it's an integer so fin >> word only reads the integer portion of the inputs. 5.675207 is read as 5. the .675207 is left in the file stream for fin >> points[count]. Words isn't stored anywhere to the 5 is discarded but the .675207 lives on as 0.675207 in points[0].
Where the negative signs are going I didn't bother trying to figure out because
while (fin >> points[count])
{
++count;
}
fixes everything.
When you read in the numbers from the the file you are extracting them as "word" and then storing them as "points". "word" is an integer and "points" is a double, this will give you unexpected behavior. The compiler should give you warnings about this.

Looping over all files in a folder to proceed script

I attached a simplified C++ code which read a data from a file and get average over the vector and save the output into csv. file. My problem is I have 100 files which named test1.csv, test2.csv,... test100.csv and do the same job for 100 files recursively and want to save the each output as result1.cvs, result2.csv, ... result100.csv respectively.
Frankly, I am a frequent use for Matlab/R and with that this loop is easy to implement but as a beginner for C++, I am puzzling from the beginning.
Each file has one vector of different historical stock price data with same length stock prices (like apple, microsoft, IBM, GM....).
Following is simplified code for your reference but actual code is very complicated one which will generate 25000*30000 matrix output,each.
Sample data in the data file is like;
45.78
67.90
87.12
34.89
34.60
29.98
......
Thanks you for your help in advance.
#include <fstream>
#include <iostream>
int main() {
//std::ifstream infile ("E:\\DATA\\test1.txt");
std::ifstream infile ("E:\\DATA\\test1.csv");
float num;
float total = 0.0f;
unsigned int count = 0;
// While infile successfully extracted numbers from the stream
while(infile >> num) {
total += num;
++count;
}
// don't need the file anymore, close it
infile.close();
// test to see if anything was read (prevent divide by 0)
if (!count) {
std::cerr << "Couldn't read any numbers!" << std::endl;
return 1;
}
// give the average
std::cout << "The average was: " << total/count << std::endl;
std::cout << "The sum was: " << total << std::endl;
std::cout << "The length was: " << count << std::endl;
// pause the console
// std::cin.sync();
//std::cin.get();
std::ofstream myfile;
myfile.open ("E:\\DATA\\result1.csv"); //check!!!!
myfile<<total/count<<","; //Add "," for csc format
myfile.close();
std::cout << "average was sucessfully saved !!!! /n";
return 0;
}
//source http://www.cplusplus.com/forum/general/124221/
It sounds like it would be easiest to run this code in a for loop, updating the filename strings with each iteration. For example:
#include <string>
#include <iostream>
#include <fstream>
int main() {
for (int i = 1; i <= 100; i++) {
std::string inFile;
std::string outFile;
// Add the prefix to the filename
inFile.append("test");
outFile.append("result");
// Add the number to the filename
inFile.append(std::to_string(i));
outFile.append(std::to_string(i));
// Add the suffix to the filename
inFile.append(".csv");
outFile.append(".csv");
// std::cout << inFile << std::endl;
// std::cout << outFile << std::endl;
std::ifstream fin;
std::ofstream fout;
fin.open(inFile);
fout.open(outFile);
// TODO:Use fin and fout
}
return 0;
}
You could also do this with character arrays (C-Strings) if you're more comfortable with that, or if you only have an older version of C++, but the concept is the same. Create a string that concatenates the file prefix, the file number, and the file suffix, and open that instead of hard-coding the filename.

reading row from text file into two vectors c++

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;
}