Reading from file upto a special character - c++

I have a file whose contain is like this:
10003;Tony;Stark;6:3:1990;Avengers Tower;New York City;12222;Iron Man
I want to read it like this
10003
Tony
Stark
6:3:1990......
I have tried upto this but couldn't seems to go further. I am trying to read up to the ;
std::ifstream file;
file.open ("OUT.txt")
while (in)
std::cout << char(in.get());

You can read each line and you can assign letters to a string until detecting ';':
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream file;
file.open("/directory of ur txt file/example.txt",ios_base::app);
string lines;
while(!file.eof())
{
getline(file,lines);
string desired_word = "";
for(int i=0;i<lines.length();i++)
{
if(lines[i] != ';')
desired_word += lines[i];
if(lines[i]==';')
{
cout<<desired_word<<endl;
desired_word = "";
}
}
}
return 0;
}

You can use std::getline with ';' as the delimiter.
std::ifstream file;
file.open ("OUT.txt")
for (std::string item; std::getline(file, item, ';'); )
std::cout << item << std::endl;

Related

How to jump a line in a file using C++

I want to increase the second line in my file, but I can't. How can I do it?
Here is my file content
0
0
I want to increase the second '0' by 1. Here is my code:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::fstream file;
file.open("file1.txt");
std::string line;
getline(file, line);
getline(file, line);
int a = std::stoi(line);
++a;
line = std::to_string(a);
file.close();
file.open("file1.txt");
std::string line1;
getline(file, line1);
getline(file, line1);
file << line;
file.close();
}
You are trying too hard. This is the easy way
int main()
{
std::ifstream file_in("file1.txt");
int a, b;
file_in >> a >> b;
file_in.close();
++b;
std::ofstream file_out("file1.txt");
file_out << a << '\n' << b << '\n';
file_out.close();
}
Read the whole contents of the file. Make the modification needed. Write the whole contents of the file.
Doing partial updates (as you are trying) can be done, but it's tricky.

Read array of objects from file by custom separator

I have model class for my objects:
class customClass {
string s1;
string s2;
string s3;
}
and file like this:
text1;text1;text1 text1 text1...
text2;text2;text2 text2 text2...
...
and I want make array of objects where
s1 = "text1"
s2 = "text1"
s3 = "text1 text1 text1..."
...
My code:
infile.open("file.txt");
if (infile.is_open())
{
string line;
for (int i = 0; i < 3; i++)
{
infile >> line;
stringstream ss(line);
while (ss.good())
{
string substring;
getline(ss, substring, ';');
cout << substring <<endl;
}
}
}
But it separated every single word. How can I ignore whitespaces to make my 3rd string as text not as single word.
The reason it doesnt work for you is because infile >> line; will read up to the first space character instead of the whole line (this is when you need getline). Maybe something like this:
#include <string>
#include <iostream>
#include <fstream>
int main()
{
std::ofstream outfile("file.txt");
outfile <<
R"(text1;text1;text1 text1 text1...
text2;text2;text2 text2 text2...)";
outfile.close();
// read file
std::ifstream infile("file.txt");
std::string par1, par2, par3;
while (std::getline(infile, par1, ';') && std::getline(infile, par2, ';') && std::getline(infile, par3))
std::cout << par1 << " | " << par2 << " | " << par3 << std::endl;
}
Demo: http://coliru.stacked-crooked.com/view?id=eb52001b5d4ecbed
Read all line with getline function. Default >> operation get values until \n, (space) character.
#include <iostream>
#include <fstream>
#include <string.h>
#include <sstream>
using namespace std;
class CustomClass
{
public:
string s1;
string s2;
string s3;
};
int main()
{
ifstream infile;
infile.open("test.txt");
if (infile.is_open())
{
while (!infile.eof())
{
string line;
getline(infile, line);
stringstream ss(line);
CustomClass cls;
getline(ss, cls.s1, ';');
getline(ss, cls.s2, ';');
getline(ss, cls.s3, ';');
cout << cls.s1 << " - " << cls.s2 << " - " << cls.s3 << endl;
}
}
return 0;
}
Just don't read single string at the begining, also I added the loop until the end of file, so your code would look like:
std::ifstream infile("file.txt");
std::string line;
if (infile.is_open())
{
string line;
while (std::getline(infile, line)) {
std::stringstream ss(line);
string substring;
while (getline(ss, substring, ';')) {
cout << substring <<endl;
}
}
}

How can I find and replace a line of data in a text file c++

I am trying to find and replace a line of data in a text file in c++. But I honestly have no idea where to start.
I was thinking of using
replaceNumber.open("test.txt", ios::in | ios::out | ios_base::beg | ios::app);
To open the file at the beginning and append over it but this doesn't work.
Does anyone know of a way to achieve this task?
Thanks
Edit: My text file is only one line and it contains a number for example 504. The user then specifies a number to subtract then the result of that should replace the original number in the text file.
Yes, you can do this using std::fstream, here's a quick implementation i whipped up real quick. You open the file, iterate over each line in the file, and replace any occurrences of your substring. After replacing the substring, store the line into a vector of strings, close the file, reopen it with std::ios::trunc, and write each line back to the empty file.
std::fstream file("test.txt", std::ios::in);
if(file.is_open()) {
std::string replace = "bar";
std::string replace_with = "foo";
std::string line;
std::vector<std::string> lines;
while(std::getline(file, line)) {
std::cout << line << std::endl;
std::string::size_type pos = 0;
while ((pos = line.find(replace, pos)) != std::string::npos){
line.replace(pos, line.size(), replace_with);
pos += replace_with.size();
}
lines.push_back(line);
}
file.close();
file.open("test.txt", std::ios::out | std::ios::trunc);
for(const auto& i : lines) {
file << i << std::endl;
}
}
You can use std::stringstream to convert the string read from the file to an integer and use std::ofstream with std::ofstream::trunc to overwrite the file.
#include <iostream>
#include <string>
#include <fstream>
#include <list>
#include <iomanip>
#include <sstream>
int main()
{
std::ifstream ifs("test.txt");
std::string line;
int num, other_num;
if(std::getline(ifs,line))
{
std::stringstream ss;
ss << line;
ss >> num;
}
else
{
std::cerr << "Error reading line from file" << std::endl;
return 1;
}
std::cout << "Enter a number to subtract from " << num << std::endl;
std::cin >> other_num;
int diff = num-other_num;
ifs.close();
//std::ofstream::trunc tells the OS to overwrite the file
std::ofstream ofs("test.txt",std::ofstream::trunc);
ofs << diff << std::endl;
ofs.close();
return 0;
}

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

How do I parse a file with line breaks as a delimiter in c++?

I was wondering how I would go about splitting a text file, chunk by chunk, and storing groups of lines as a single string.. For example:
I have a text file of questions, some of which are multiple lines. After a variable number of lines (depending on how many lines the question takes up) there is a blank line, then the answer, followed by another question (which could also be longer than 1 line), blank line, answer.
Something like this, where "q" are lines that should be stored as a single string and "a" should also be a single string:
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
aaaaaaaaaaaaaaaaaaaaaaa
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
I tried reading line by line, combining string line + line if line != "". But it got confusing and messy and I couldn't ever get it to work correctly.
I simply want to store the first set of q's as a single string and put it in vector[0] and the first set of a's in vector[1]. The second set of q's in vector[2]. The second set of a's in vector[3].. and so on. Both the q's and the a's can be several lines.
Any suggestions or help will be much appreciated!
#include <vector>
#include <fstream>
#include <iostream>
#include "Question.h"
#include <iomanip>
using namespace std;
int main(int argc, char * argv[]){
ifstream infile;
string filename = "questions.txt";//manually set for testing.
//cout<<"Enter the questions file: ";
//cin>>filename;
infile.open(filename.c_str());
if (!infile){
cout<<"error"<<endl;
return 0;
}
else {
cout<<"file opened!"<<endl;
}
vector<string> myvector;
string line;
string additionalLine;
int totalLines = 0;
while(getline(infile,line)){
totalLines++;
}
cout<<"total lines: "<<totalLines<<endl;
/*
while(getline(infile,line,'\n')){
cout<<line<<endl;
}
*/
while(getline(infile,line,\n)){
if (line == ""){
cout<<"empty"<<endl;
}
else {
cout<<"line is not empty"<<endl;
additionalLine = additionalLine + line;
}
if (line != ""){
myvector.push_back(additionalLine);
}
}
for(int i=0; i < (myvector.size()); i++){
cout<<myvector[i]<<endl;
}
//TESTING
cout<<"Question: "<<endl;
cout<<myvector[0]<<endl;
cout<<"Answer: "<<endl;
cout<<myvector[1]<<endl;
return 0;
}
I tweaked the code a bit and got it to work!
I changed the way I approached cycling through the lines of the text file, changing it to while (!infile.eof()) and manually got the lines. I also added a statement to detect if there was a new line. I also had to reposition where I reset the string variables back to "".
Thanks for the suggestions! Heres the solution code:
#include <vector>
#include <fstream>
#include <iostream>
#include "Question.h"
#include <iomanip>
using namespace std;
int main(int argc, char * argv[]){
ifstream infile;
string filename = "questions.txt";//manually set for testing.
//cout<<"Enter the questions file: ";
//cin>>filename;
infile.open(filename.c_str());
if (!infile){
cout<<"error"<<endl;
return 0;
}
else {
cout<<"file opened!"<<endl;
}
vector<string> myVec;
string line;
string comboLine="";
while(!infile.eof()){
getline(infile,line);
if (line == "" || line == "\0") {
//cout<<"->BLANK LINE DETECTED<-"<<endl;
myVec.push_back(comboLine);
comboLine="";
}else {
comboLine = comboLine + line;
//cout<<"comb: "<<comboLine<<endl;
}
line = "";
}
infile.close();
//TESTING
cout<<"Question: "<<endl;
cout<<myVec[0]<<endl;
cout<<"Answer: "<<endl;
cout<<myVec[1]<<endl;
cout<<"Question 2: "<<endl<<myVec[2]<<endl;
cout<<"Answer 2: "<<endl<<myVec[3]<<endl;
return 0;
}
If you're using Qt, you can do this easily.
QFile myFile;
myFile.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream openFile(&myFile);
while (!myFile.atEnd()) {
QString line;
QStringList tokens;
line = myFile.readLine();
tokens = line.split("\n");
// additional processing here with your tokens, which are delimited by '\n'
}
You will need to include QFile, QString, QTextStream and QStringList for this to work. Good luck!
struct QA {
vector<string> questionLines;
vector<string> answerLines;
};
vector<string> getLines(istream& is) {
vector<string> lines;
string line;
do {
getline(is, line);
lines.push_back(line);
} while(!line.empty())
return lines;
}
istream operator>>(istream& is, QA& qa) {
qa.questionLines = getLines(is);
qa.answerLines = getLines(is);
}