write data at desired line in already existing file - c++

I have a text file which already has 40 lines of data . I want to write data just before last two lines in a file. I am newbie to c++. I searched online and found few functions like fseek and seekp, but I am not getting how those those functions to change the lines. Can you please give some pointers for this?
Thank you in advance.

Open your file using a std::ifstream
Read the whole file into a std::vector<std::string> with an entry for each line in the file (you can use std::getline() and std::vector<std::string>::push_back() methods to realize this).
Close the std::ifstream
Change the vector entry at the line index you want to change, or alternatively insert additional entries to the vector using std::vector<std::string>::insert()
Open your file using a std::ofstream
Write the vectors content back to the file (just iterate over the vector and output each entry to the file).
You shouldn't mess around with seek functions in this case; particularly not, if the replacements size changes dynamically.

You say C++, so I assume you mean that and not C. A FIFO comes to mind for this purpose.
$ cat last_two_lines.c | ./a.out
#include <iostream>
#include <string>
#include <deque>
main ()
{
std::deque<std::string> fifo;
while (!std::cin.eof()) {
std::string buffer;
std::getline(std::cin, buffer);
fifo.push_back(buffer);
if (fifo.size() > 2) {
std::cout << fifo.front() << "\n";
fifo.pop_front();
}
}
std::cout << " // LINE INSERTED" << "\n";
while (fifo.size() > 0) {
std::cout << fifo.front() << "\n";
fifo.pop_front();
}
return 0;
// LINE INSERTED
}

Related

C++ and reading large txt files

I have a lot of txt files, around 10GB. What should I use in my program to merge them into one file without duplicates? I want to make sure each line in my output file will be unique.
I was thinking about making some kind of hash tree and use MPI. I want it to be effective.
build a table of files, so you can give every filename simply a number (a std::vector<std::string> works just fine for that).
For each file in a table: open it, do the following:
read a line. Hash the line.
Have a std::multimap that maps line hashes (step 3) to std::pair<uint32_t filenumber, size_t byte_start_of_line>. If your new line hash is already in the hash table, open the specified file, seek to the specified position, and check whether your new line and the old line are identical or just share the same hash.
if identical, skip; if different or not yet present: add new entry to map, write line to output file
read next line (i.e., go to step 3)
This only takes the RAM needed for the longest line, plus enough RAM for the filenames + file numbers plus overhead, plus the space for the map, which should be far less than the actual lines. Since 10GB isn't really much text, it's relatively unlikely you'll have hash collisions, so you might as well skip the "check with the existing file" part if you're not after certainty, but a sufficiently high probability that all lines are in your output.
If you don't have requirements to keep the memory usage low, you could just read all the lines from all the files into a std::set or std::unordered_set. An unordered_set is as the name implies not ordered in any particular way while a set is (lexicographical sort order). I've chosen a std::set here, but you can try with a std::unordered_set to see if that speeds things up a little.
Example:
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
#include <set>
#include <string>
#include <string_view>
#include <vector>
int cppmain(std::string_view program, std::vector<std::string_view> args) {
if(args.empty()) {
std::cerr << "USAGE: " << program << " files...\n";
return 1;
}
std::set<std::string> result; // to store all the unique lines
// loop over all the filenames the user supplied
for(auto& filename : args) {
// try to open the file
if(std::ifstream ifs(filename.data()); ifs) {
std::string line;
// read all lines and put them in the set:
while(std::getline(ifs, line)) result.insert(line);
} else {
std::cerr << filename << ": " << std::strerror(errno) << '\n';
return 1;
}
}
for(auto line : result) {
// ... manipulate the unique line here ...
std::cout << line << '\n'; // and print the result
}
return 0;
}
int main(int argc, char* argv[]) {
return cppmain(argv[0], {argv + 1, argv + argc});
}

c++ copying console values to a csv

New in C++ and I am trying to copy the values that I read on my console after opening a .csv file to another .csv file that I want to create. Unfortunately it copies only the last value, not the whole. Any help? thanks very much!
int main()
{
ifstream filetocopy("ecommerce.csv");
int d;
while(filetocopy>>d){
cout << d << endl;}
ofstream numbers("testing.csv");
numbers << d << endl;
}
Obvious problems with your approach:
1) You create the output file after you read the entire input file which means you write only the last value to the output file.
2) Even if you fix 1) you would still write the csv values in a wrong order to the output file. Suggestion: read line by line -> print the line on the console -> write the line to the file.
Here's a simple solution to your problem (just an example you can improve it):
#include <iostream>
#include <fstream>
#include <string>
int main () {
std::ifstream filetocopy("ecommerce.csv");
std::ofstream numbers("testing.csv");
std::string line;
while(std::getline(filetocopy, line)) {
std::cout << line << std::endl;
numbers << line << std::endl;
}
return 0;
}
You have two problems here.
First, you didn't create the ofstream to output until after you had already used and discarded most of your data.
Second, in the while loop, all you did was write your data to the standard output and not to file.
To correct the problem, you need to move the ofstream initialization before the while loop and move numbers << d << endl; into the loop.
Think of your ifstream as like an old VCR tape. As you are printing out characters with that while loop
while(filetocopy>>d){
cout << d << endl;}
your ifstream finished "playing". Every loop d gets a new frame of the tape and prints it out. So the tapehead is at the end, and now d is just holding onto the last frame of the credits. So when you write it to your new csv, that's the only value it has left.
Try not printing out all those values first.

How to show contents of the file in C++

I have some code here
https://github.com/Fallauthy/Projects/blob/master/cPlusPlusProjects/bazaPracownikow/bazaPracownikow/bazaPracownikow/main.cpp
And I have no idea how to show contents in my file. I mean i know how, but it doesn't show same I Have in file (in link). It show in next line. This code is responsible to load file
while (!baseFile.eof()) {
//wczytaj zawartosc pliku do zmiennej
std::string buffer;
baseFile >> buffer;
//wypisz
loadLineFromBase += buffer;
loadLineFromBase += " \n";
}
std::cout << loadLineFromBase << std::endl;
Unless I see all your code all I can do for you is give you a sample in return, I don't know what you're trying to do but it seems in this case you're looking for this.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string Display = "";
ofstream FileOut;
ifstream FileInput;
FileOut.open("C:\\Example.txt");
FileOut << "This is some example text that will be written to the file!";
FileOut.close();
FileInput.open("C:\\Example.txt");
if (!FileInput)
{
cout << "Error File not Found: " << endl;
return 1;
}
while (!FileInput.eof())
{
getline(FileInput, Display);
}
FileInput.close();
cout << Display << endl;
return 0;
}
Simply put if you're currently working wit ha text document
use getline()
When you use getline() it takes two arguments the first will be in this case your ifstream object, as in what you're using to open the file. The second will be the string you're using to store the contents in.
Using the method I outlined above you'll be able to read the entire file contents.
And please next time as it was said above outline your problem more in depth and if you provide us with all of your code we may better assist you!
Your snippet of code automatically add a newline to every string read from the input file, even if originally those were words separeted by spaces. Probably you want to keep the structure of the original file, so it's better to read one line at a time and, unless you need it for some other uses, print it out in the same loop.
std::string buffer;
// read every line of baseFile till EOF
while ( std::getline(baseFile, buffer) ) {
std::cout << buffer << '\n';
}

Code to print out number of lines and integer values

I created a data file called program.txt. I need to create code that prints out number of lines and integer values from that program.txt
Heres the text I made
1
35
45
87
9
100
the program.text has these values in it
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string calc;
int test;
int cool;
int book;
ifstream myfile;
ifstream outof;
myfile.open ("program.txt");
outof.open("program.txt");
if (myfile.fail())
{
cerr<<"Error Opening file"<<endl;
}
if(outof.fail ())
{
cerr<<"Error Opening file"<<endl;
}
while (!myfile.eof ())
{
getline(myfile,calc);
++book;
}
cout <<book<<endl;
while (!outof.eof ())
{
outof<<test;//
cool++;
}
cout<<cool<<endl;
myfile.close();
outof.close();
}
Also after cerr I tried exit (1) and it said exit was not defined.
I am new to this any help would be greatly appreciated. Thanks This is C++ btw.
The problem is that you are using ifstream, which stands for INPUT file stream. You want to use ofstream, which is OUTPUT file stream. You cannot write to an input file stream, hence why the << operator is not defined.
Also, rather than using exit(1) after your errors, you can just return 1; as you are inside your main function. This will terminate the program, returning 1 as the exit code.
If you really want to use exit, you need to #include <cstdlib>.
Your defined input and expected output aren't clearly defined, so I'm not sure what you're trying to do. However, here's a general idea:
Putting the filename in a fstream's constructor will automatically try to open the file for read/write. You dont need to call .open() anymore. Also, you shouldnt be reading and writing to the same file simultaneously if you dont know what you're doing.
std::ifstream myInputFile("program.txt");
std::ofstream myOutputFile("programOut.txt");
Rather than checking myInputFile.fail(), just use the overloaded boolean operator. In depth explanation: ifstream::is_open vs ifstream::fail?
if (!myInputFile) {
//Something went wrong
std::cerr << "Failed to open input file" << std::endl;
return 1;
}
Define your std::string to hold lines as you read them, read all of your input file, and count the lines.
std::string line;
int lineCount = 0;
while (getline(myInputFile,line)) {
++lineCount;
//Do something with 'line'
}
Maybe you'll need to store the lines from your input file so that you can output the count of the lines at the beginning of your output file, you might want to #include <vector> and do something like this:
std::string line;
std::vector<std::string> linesFromFile;
//Read in all lines of the input file and store them in the vector
while (getline(myInputFile, line)) {
linesFromFile.emplace_back(line);
}
//All lines read, good time to close input file
myInputFile.close();
//Print number of lines read
myOutputFile << linesFromFile.size() << std::endl;
//Loop through lines and print them
for (auto &lineFromFile : linesFromFile) {
myOutputFile << lineFromFile << std::endl;
}
//Done outputting, close output file
myOutputFile.close();

text from a file turned into a variable?

If I made a program that stores strings on a text file using the "list"-function(#include ), and then I want to copy all of the text from that file and call it something(so I can tell the program to type in all of the text I copied somewhere by using that one variable to refer to the text), do I use a string,double,int or what do I declare that chunk of text as?
I'm making the program using c++ in a simple console application.
Easier explanation for PoweRoy:
I have a text in a .txt file,I want to copy everything in it and then all this that I just copied, I want to call it "int text" or "string text" or whatever.But I don't know which one of those "int","string","double" etc. to use.
To take some pity on you, this is about the simplest C++ program that reads a file into memory and then does something with it:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main() {
ifstream input( "foo.txt" );
if ( ! input.is_open() ) {
cerr << "could not open input file" << endl;
return 1;
}
vector <string> lines;
string line;
while( getline( input, line ) ) {
lines.push_back( line );
}
for ( unsigned int i = 0; i < lines.size(); i++ ) {
cout << (i+1) << ": " << lines[i] << "\n";
}
}
Broadly speaking, you are talking about the concept of Serialization - storing variable values in permanent storage like a file so you can reload them later. Have a look at that link to broaden your understanding.
Specifically, it sounds like you have arbitrary text in a file and want to refer to it in your program. In that case, string sounds appropriate. Unless the text in the file is intended to represent one single number, that seems most appropriate.
Note that if you have structured data (like a CSV file or XML file), a more complex data structure (e.g. a class, array of classes, etc) might be a better choice.
#include <iostream>
#include <fstream>
#include <string>
int main() {
// Open stream from file
std::ifstream ifs("foo.txt");
// Get file contents
std::string file_contents(
(std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>()
);
// Output string to terminal to see that it works
std::cout << file_contents;
}