Looping over all files in a folder to proceed script - c++

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.

Related

looping over numbers from a txt file using fstream

I'm a bit new to C++ so I'm trying to keep things simple.
I'm trying to apply a loop that simply prints out each number from a txt file. And there are A LOT of numbers.
I've been trying to do this with a for loop but with no success. Here's just one of my attempts:
int main() {
fstream myFile;
myFile.open("resources/numbers.txt");
if (myFile) {
cout << "This file is opened\n";
}
else
return EXIT_FAILURE;
for (i = 1; i<n; i++){
myFile >> n;
cout << n;
}
return 0;
}
I'd prefer not to use arrays or getLine. I just want to take every number from the txt file and print it to the user until every number is printed.
Is there an easy way to do this?
Thanks a million!
Here is how I’d print the number in the file:
std::copy(std::istream_iterator<int>(myFile),
std::istream_iterator<int>(),
std::ostream_iterator<int>(std::cout, “\n”));
In you example you didn’t declare n so it isn’t clear what the proper type is. The code assumes int and that <algorithm> and <iterator> are included.
#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <fstream>
int main()
{
std::ifstream myFile{ "resources/numbers.txt" }; // use c-tor to open
// ^ ifstream ... we only want to read
if (!myFile.is_open()) {
std::cerr << "File couldn't be opened for reading :(\n\n";
return EXIT_FAILURE;
}
std::cout << "File is open for reading.\n\n";
int number;
while(myFile >> number) // as long as integers can be extracted from the stream,
std::cout << number << '\n'; // print them.
} // no need to return anything as main() returns 0 when not return statement
// is present.

Read from binary file > data into class object, missing data

I'm currently making a file that reads ASCII file to read binary file instead. It has to put data into an object named Arragements and Customers. However, something is missing. It does not read the first line of the files.
It is reading everything correctly (it seems), except the fact that it doesn't read the first line of the file at all, and instead it adds 5 zeros at the end when it is supposed to not be anything there. In other words, it is not reading everything. Any big mistakes made? I'm changing the code from reading a ASCII file to read a BINARY file instead. If it make any changes, I've added how the readTicketsFromFile looked like when it was written to read ASCII file blow.
Here's the code when reading from ASCII: https://pastebin.com/WswHzpxM
The file format is (10 lines total):
< nr (2) > < amount tickets(4) > < price(3) > < title(30) >
Here's what I ried to make, "translating" the code to read same file in BINARY (It is obviously converted to BINARY file):
#include <fstream> // ifstream, ofstream
#include <iostream> // cout
#include <cstring> // strcpy
#include <cstdlib> // (s)rand
using namespace std;
const int ARRLEN = 35;
// CLASSES
class Arrangement {
private:
char title[ARRLEN]; // Arrangement title/name
int price; // Price pr. ticket
int amountSpaces; // Amounts of spaces/tickets left
int amountSold; // Amounts of tickets sold so far
int totalTicketsOrdered; // Total amount of tickets
int totalCustomersOrdered; // Amount of customers wanting a ticket
public:
Arrangement();
void update(char titt[], int ant, int pri);
void updateAmountWishedTickets(int antBill);
void updateAmountSold(int ant);
bool needPull();
int amountLeft();
int amountOrdered();
void write()
{
cout
<< '\n' << price << "\t"
<< amountSpaces << "\t"
<< amountSold << "\t"
<< totalTicketsOrdered
<< "\t" << totalCustomersOrdered
<< '\t' << title;
}
};
// READ FROM FILE 1
void readTicketsFromFile() {
char title[ARRLEN];
int nr, amount, price; // Variables 3 first "spaces" of the file
int size = 0;
// post/linje på filen.
ifstream infile;
infile.open("tickets.res", ios::in | ios::binary);
if (infile.is_open()) {
infile.seekg(0, ios::end);
size = (int)infile.tellg() / sizeof(Arrangement);
cout << "\n# in file: " << size << endl; // Prints out: 10
// Read from file, supposed to read everything from the file
for (int i = 1; i <= size; i++) {
infile.seekg(i * sizeof(Arrangement));
infile.read((char *)& arrangementer[i], sizeof(Arrangement));
cout << '\n' << i << " read: \n";
arrangementer[i].write(); // Used to see what what's inside the object, 1. missing.
}
}
else cout << "Couldn't open the file";
infile.close();
}
int main() {
readTicketsFromFile();
return 0;
}
What it shoud look like:
https://i.gyazo.com/69c5560766c33ebc15cac25e13b4de72.png
What it looks like:
https://i.gyazo.com/a9081f65ff629f3b57cb2c20750087b5.png

reading data file for root cern graphing

I created a script to take data from a text file and graph it in Root (CERN) but haven't used root in about a year, updated to the current version of Root and now it gets the error "Error: Function readprn() is not defined in current scope :0:
* Interpreter error recovered *" when i try to use it with Root.
It runs an excel data file that I saved as a txt file. The first column is the x value corresponding to each y value in the subsequent 768 columns. At the end it graphs and fits and loops over a couple graphs.
I'm mostly wondering if there is anything in the new versions that would cause this to not be able to be read by root.
#include <TGraph.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TMath.h>
#include <TStyle.h>
#include <iostream>
#include <fstream>
#include <string>
using std::cout; using std::endl;
int threshold1(Int_t channel=0)
{
const char* ifname = "thresholdScanRun110FPGA4.txt";
cout<< "processing file " << ifname <<endl;
std::ifstream ifile(ifname);
if (!ifile) {
cout<< "Could not find file " << ifname <<endl;
return 0;
}
//std::string line;
// discard the first two lines
//std::getline(ifile, line);
//cout<< line <<endl;
//std::getline(ifile, line);
//cout<< line <<endl;
std::string str;
double number;
// read the first row (in sense of Exel's row)
ifile >> str;
//cout<< str <<endl;
for (int i=0; i<768; ++i) {
ifile >> number;
//cout<< number << " ";
}
//cout<<endl;
// read the second "row"
ifile >> str;
//cout<< str <<endl;
for (int i=0; i<768; ++i) {
ifile >> number;
//cout<< number << " ";
}
//cout<<endl;
double thres[60];
double prob[60][768];
int nthres_max = 60;
for (int ithres=0; ithres<nthres_max; ++ithres) {
ifile >> thres[ithres];
for (int iprob=0; iprob<768; ++iprob) ifile >> prob[ithres][iprob];
}
cout<< "The channel " << channel <<endl;
for (int ithres=0; ithres<60; ++ithres) {
cout<< thres[ithres] << " " << prob[ithres][channel] <<endl;
}
Double_t probability[60];
for (int ithres=0; ithres<60; ++ithres) probability[ithres] = prob[ithres][channel];
TGraph* gr = new TGraph(60, thres, probability);
gr->SetMarkerStyle(29);
gr->SetMarkerColor(4);
gr->SetTitle("Threshold Scan ChipX, ChanY");
TF1* ferfc = new TF1("ferfc", "0.5*TMath::Erfc((x-[0])/[1])", 0, 767);
ferfc->SetParameters(100,10);
new TCanvas;
gStyle->SetOptFit(1);
gr->Draw("apl");
gr->Fit("ferfc");
return 0;
}
int threshold_all()
{
for (Int_t channel=0; channel<2; ++channel) {
threshold1(channel);
}
}
when loading your macro in root 6.07/04, with .L macro.C I receive the following warning:
/tmp/tmp.rQTNVdlydv/macro.C:88:1: error: control reaches end of non-void function [-Werror,-Wreturn-type]
which is because you don't have a return statement in int threshold_all(). Fixing this the macro seems fine to me. (runs, opens a canvas, some fit output. Since I don't have your input values, I just created a text file with a few invented numbers and reduced the number of thresholds and values to 5x6. Which is why I'm not concerned about the abnormal fit termination which I receive.).
Also loading the macro with compilation .L macro.C+ looks fine to me once adding the return statement.

Not getting all lines from a text file when using getline() in C++

I was given a homework assignment to generate a txt file containing a random number of lines, each with a random amount of integers, ranging between a minimum value and a maximum value. Lots of rand() fun.
In any case, that was the easy part. The second part of the problem is to read over the first file and create a second file that contains some statistics, such as: the sum of all integers in the file, their average, min and max values, and my main issue: the sum of all integers in each line.
I have written the following code:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cmath>
using namespace std;
int main()
{
string newLine;
stringstream ss;
int newInput = 0, oldInput = 0;
int lineSum = 0;
int lineCounter = 0;
int allSum = 0;
int intCounter = 0;
double averageOfAll = 0;
int minInt = 0;
int maxInt = 0;
.... // generating the first file. No issues here.
ifstream readFile;
readFile.open("inputFile.txt");
ofstream statFile;
statFile.open("stat.txt");
if(readFile.is_open()) {
while (getline(readFile, newLine)) { //my problem should be somewhere
//around here...
ss.str("");
ss << newLine;
while(!ss.eof()) {
oldInput = newInput;
ss >> newInput;
cout << newInput << endl;
lineSum += newInput;
allSum += newInput;
intCounter++;
minInt = min(oldInput, newInput);
maxInt = max(oldInput, newInput);
}
lineCounter++;
statFile << "The sum of all integers in line " << lineCounter
<< " is: " << lineSum << endl;
lineSum = 0;
}
readFile.close();
averageOfAll = static_cast<double>(allSum)/intCounter;
statFile << endl << endl << "The sum of all integers in the whole file: "
<< allSum;
statFile << endl << "The average of value of the whole stream of numbers: "
<< averageOfAll;
statFile << endl << "The minimum integer in the input file: "
<< minInt;
statFile << endl << "The maximum integer in the input file: "
<< maxInt;
statFile << endl << endl << "End of file\n";
} else
cout << endl << "ERROR: Unable to open file.\n";
statFile.close();
return 0;
}
When running the program, it seems like my loops do iterate over all the lines in the file. However, they only collect the integers from the first line, and the rest remains 0.
I would post screenshots of my outputs, but I do not have enough rep :(
can anyone help out?
It worked!
inputFile.txt ^
statFile.txt (my output) ^
And like P0W and James Kanze suggested, it was a flag issue and a misuse of my streamstring. I corrected my code as follows:
.
.
.
while (getline(readFile, newLine)) {
stringstream ss(newLine);
while(ss >> newInput) {
lineSum += newInput;
allSum += newInput;
intCounter++;
minInt = min(minInt, newInput);
maxInt = max(maxInt, newInput);
}
.
.
.
Thank you all!
There are several issues, but the main one is that you're trying
to reuse ss (which should properly be an
std::istringstream). It's possible to do so, but it's fairly
difficult to get right, since streams hold a lot of state which
needs reinitializing. (In this case, the stream memorizes that
it has seen end of file, and doesn't do anything else until that
has been reset.) Your loop should look like:
while ( getline( readFile, newLine ) ) {
std::istringstream ss( newLine );
// ...
}
And once you've got the std::istringstream, you don't want to
loop until eof (which may or may not be set after the last
successful input); you want to loop until an input fails.
(After the input fails, you may want to check eof: if it
isn't set, the input failed because of a format error in the
line; e.g. someone entered "abc" instead of an integer.)
You can try following for your inner while loop
ss << newLine;
while( ss >> newInput )
{
//.... Your logic,
// might need little update
oldInput = newInput;
}
ss.clear( ); // clear the flags !

How to read txt file into vector and cout the file?

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