how can I make the code read different files? - c++

how can I make the code read different files
infile.open("C:\\Users\\kujak\\Desktop\\simmac1\\job_1.txt");
like i want to read job_1 then job_2 and on

It really depends on what you are trying to do, but the simple way is the one suggested by #drescherjm which is store it in a std::string:
for(int i=0;i<loop_control;i++) {
std::string path = "My/Path/job_" + std::to_string(i) + ".txt";
ifstream infile(path);
//...
}
Something like that should work.

Related

ifstream read every files that start with

I have multiple files that start with employee_
Examples :
employee_2053.txt
employee_1284.txt
employee_4302.txt
etc...
What I want is to read the content of every file. I tried something like this:
string fname, lname;
ifstream file("employee_" + *);
while(file>>fname>>lname) {
// Do something here that is gonna be repeated for every file
}
I have an error at "employee_" + *. When I think about it, it makes sense that it doesn't work. I guess I will need a loop or something, I just don't know how to do it.
Enumerate the available files using the OS specific API and store the names inside a container such as vector of strings std::vector<std::string> v;. Iterate over a container:
for (auto el : v) {
std::ifstream file(el);
// the code
}
If you know for sure there are existing files with range based hard coded values you can utilize the std::to_string function inside a for loop:
for (size_t i = 0; i < 4000; i++) {
std::ifstream file("employee_" + std::to_string(i) + ".txt");
// the code
}
Update:
As pointed out in the comments the alternative to OS API is a file system support in the C++17 standard and the Boost Filesystem Library.

I want to create a text file in cpp using ofstream

I want to create a file qbc.txt. I know how to create it, but I want to create a program that, if a file already exists with the same name, it would rename it to qbc(1).txt.
In C++17, boost's filesystem library was standardized as std::filesystem
It comes with a convenient std::filesystem::exists function.
It accepts a std::filesystem::path object, but fortunately those can be constructed with a std::string, making our program trivially easy:
std::string prefix = "qbc";
std::string extension = ".txt";
std::filesystem::path filename{prefix + extension};
int i = 0;
while (std::filesystem::exists(filename)){
filename = prefix + "(" + std::to_string(++i) + ")" + extension;
}
// now filename is "qbc(1)" or "qbc(2)" etc.
Unfortunately no compiler has full support for it at the time of this writing!
Here is a simple solution. The file_exists() function came from #Raviprakash in his response. I've added how to change the filename and try again until success. I've done an approach similar to this before in Python.
If you know that your program is the only one that will create or remove these files, then you can cache the last created one and simply create the next one instead of looping over all of the created ones every time. But this kind of optimization would only make sense if you plan to make hundreds of thousands of files this way.
#include <fstream>
#include <string>
bool file_exists(const std::string &filename) {
std::ifstream in(filename);
return in.good();
}
std::ofstream& open_new(std::ofstream &out, std::string prefix,
std::string suffix)
{
std::string filename = prefix + suffix;
unsigned int index = 0;
while (file_exists(filename)) {
index++;
filename = prefix + "(" + std::to_string(index) + ")" + suffix;
}
out.rdbuf()->open(filename, std::ios_base::out);
return out;
}
int main() {
std::string prefix = "qbc";
std::string suffix = ".txt";
std::ofstream out;
open_new(out, prefix, suffix);
out << "hello world!\n";
return 0;
}
I know the program needs some improvements but the general idea is here:
#include <fstream>
#include <string>
using namespace std;
inline bool file_exists(const std::string& name)
{
ifstream f(name.c_str());
return f.good();
}
int main()
{
string filename, name;
name = "qbc";
filename = name;
int counter = 1;
while (file_exists(filename+".txt")) {
string str = to_string(counter);
filename = name+ "(" + str + ")";
counter++;
}
filename += ".txt";
ofstream out(filename.c_str());
return 0;
}
I don't think this can be entirely solved using just the standard libraries. You can certainly keep picking a new file name until you find one that's unused and then create the new file (as the other answers have shown).
But there's an inherent race condition in that approach. What if another process creates a file between the time your program decides the name is available and the time it actually creates the file? Imagine two copies of your program both trying to write out files.
What you need is an atomic way to check for the file's existence and also to create the file. The normal way to do that is to first just try to create the file and then see if you succeeded or not. Unfortunately, I don't think the standard C++ or C libraries give you enough tools to do that. (I'd be happy to be proven wrong about that.)
Operating systems often provide APIs for doing just that. For example, Windows has GetTempFileName, which just keeps trying to create a new file until it succeeds. The key is that, once it succeeds, it keeps the file open so that it knows no other process can steal the name that's been selected.
If you tell us which OS you're using, we might be able to provide a more detailed answer.

How to read a File and save specific occuring strings?

I need to read a file, which is an .asc document using QT Framework.
I need to check the file for specific Strings, for example "(Name)".
The Numbers after the specific String have to be saved in another .txt file.
So I tried to use a for loop connected with a getline() statement, whilst an if statement should be checking if the predefined String was found already.
If the String was found I am using a string variable .assign() method to input the whole matching line to another string.
But sadly it is still not working, maybe there is a logical failure, so I am asking for your help!
std::string line;
std::string search = "(Name)";
std::string content;
std::ifstream ifs("C:/PROG/EMS/LD1/analyse_led");
for(unsigned int curLine = 0; std::getline(ifs, line); curLine++) {
if (line.find(search) != std::string::npos) {
content.assign( (std::istreambuf_iterator<char>(line) ),
(std::istreambuf_iterator<char>() ) );
}
}
Of course I implemented all related include files above, thanks for your help!
If you need more information let me know in the comments.
content and line are both std::strings, just do
content = line;
or
content = std::move(line);
if you don't need to do anything else with line afterwards. (line will be empty after this).
I'm not sure what you are trying to achieve with istreambuf_iterator, but I'm sure it isn't going to work...

Reading and writing to files isn't working in C++

I am basically trying to reverse the contents of a text file. When I run this code, nothing happens. Code:
getArguments();
stringstream ss;
ss << argument;
string fileName;
ss >> fileName;
fstream fileToReverse(fileName);
if (fileToReverse.is_open()) {
send(sock, "[*] Contents is being written to string ... ", strlen("\n[*] Contents is being written to string ... "), 0);
string line;
string contentsOfFile;
while (getline(fileToReverse, line)) {
contentsOfFile.append(line);
line = "\0";
}
send(sock, "done\n[*] File is being reversed ... ", strlen("done\n[*] File is being reversed ... "), 0);
string reversedText(contentsOfFile.length(), ' ');
int i;
int j;
for(i=0,j=contentsOfFile.length()-1;i<contentsOfFile.length();i++,j--) {
reversedText[i] = contentsOfFile[j];
}
contentsOfFile = "\0";
fileToReverse << reversedText;
fileToReverse.close();
send(sock, "done\n", strlen("done\n"), 0);
}
fileName is created from user input, and I know that the file exists. It just doesn't do anything to the file. If anyone has any ideas that they would like to share that would be great.
UPDATE:
I now can write reversedText to the file but how can I delete all of the files contents?
In this particular case, when you have read all the input content, your file is in an "error state" (eof and fail bits set in the status).
You need to clear that with fileToReverse.clear();. Your file position will also be at the end of the file, so you need to use fileToReverse.seekp(0, ios_base::beg) to set the position to the beginning.
But I, just as g-makulik, prefer to have two files, one for input and one for output. Saves a large amount of messing about.
When you need to debug something like this - saying "all the functions are being run and all the variables are being created, and it compiled without any warnings" isn't really debugging.
Debugging - this doesn't work. Remove bits until you find what doesn't work. Like you said - all variables are what you expect them. So... try and see if, for example, the way you read and write from a file works. Just write a small program that opens a file like you open it, reads from it like you do and then writes... whatever back into it in the same way you do. See if that works.
In other words, try and find the smallest program that reproduces what you see.

C++ external file read: I know how to find and read a string, findMe. But how do I deal with findMei (finding any number, i, of the string)?

Apologies in advance, because I suspect this may be a silly question.
I have written a function for reading in data from an external file. I then use the data to perform calculations using other code I have written.
The function works by finding a data label that looks like this:
const std::string findMe = "<dataLabel>";
Each time I want to find data, I replace dataLabel with the label of whichever data I need from the file.
Here's what I want to do.
I don't want to have to write in the label of the data I want each time. I want to be able to do this:
for (int i = 0; i < anyNumberOfDataSets; i++)
{
findMe = "<dataLabeli>";
// Then run function for reading in data, put data into a vector.
}
I could then add any number of data sets to my external file, give each one the title
, and have each data set read into a vector.
The problem is, I simply can't figure out how to write findMe = "<dataLabeli>". Is this even possible?
I have tried things like, findMe = "<dataLabel" << i <<, but no luck!
Any suggestions would be much appreciated.
It is very hard to understand what you mean, but I guess you want this
#include <sstream>
#include <string>
for (int i = 0; i < anyNumberOfDataSets; i++)
{
std::ostringstream strm;
strm << "<dataLabel" << i << ">";
const std::string findMe = strm.str();
//...
//proceed with searching findMe
}
You can read more about string streams, for instance, here
you've already got the right answer, so this is just trying to help you with solving such problems in the future:
Your core problem here is to convert the integer i into a string s (if you've done this, than you just do findMe = "<datalabel"; findMe += s; findMe += ">";.
Googling for c++ convert integer into string will give you this as the first result. Problem solved.
This is not saying "use google before/instead of asking", it's rather "try to identify the core problem".
Another solution:
using namespace boost;
findMe = str(format("<dataLabel%d>") % i);
This will substitute %d with the value of i, formatted like printf() does.