C++ Read and modify a line in a txt file - c++

I'm facing some difficulties with the searching of the position of the first occurrence of a word.
The software have to search into a determined txt file a specified word. So I've used the fstream lib to open and after all write something. But I have no clue how I will make the software to get the exactly position of the that word. All I got is this:
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
int main() {
fstream myfile; // fstream to read and write the myfile
string cText = "\n--something--!\n"; // what it will write
string line; // will assign the getline() value;
unsigned int pos = 0; //will be assigned to "seekp" - where it will start to write
myfile.open( "example.html", ios::binary | ios::in | ios::out );
if( !myfile ) {
cout << "File does not exist!" << endl;
cin.get();
return false;
}
do {
size_t found = line.find("<head>");
cout << string::npos << endl;
if (found != string::npos) {
cout << line << endl;
}
}while( getline(myfile, line));
myfile.seekp( pos+1, ios::beg );
//myfile.write( cText, strlen( cText ) ); //write cText
myfile.close();
cin.get();
return 0;
}
Any suggestions?

Don't try to change the bytes in your file. Make a new file, copy the lines over until you find the one you want to replace, output your new line, then output the rest of your lines. Because unless you're replacing one string, with another string with exactly the same number of characters, you're going to be overriding the next line in your file - and there's no good way to avoid that.
If you want to, you can then delete the original file, and rename your new file to that name.

Related

C++ line justification with I/O

I am creating a program that justifies a paragraph to ensure that each line has a length of 75 char. I have created functions that will insert spaces and create these desired lengths as needed, but I am having problems reading a text file and trying to break it down line by line. Each line provided is less than the 75 char limit, and my functions do properly work when it is given only a line. But I do not know how to read line by line, manipulate it, and then write to my new .txt file. When I output this to the new text file, I am greeted by a justified line of text, not text that is in a paragraph block!
I have tried to create an if else loop that would only run when the string.length() is less than 75 char, and would create a new line when false, but I do not know how to create this new line in the program
string myString;
string line("\n");
while (getline(inFile, myString))
{
cout << myString << endl;
puncLoop(myString);
spaceLoop(myString);
}
}
In Order to output the file with new line you can use "\n".
#include <iostream>
#include <string>
#include <fstream>
int main() {
//in file object
std::ifstream inFile("example.txt");
//out file object
std::ofstream outFile ("example2.txt", std::ios_base::out | std::ios_base::trunc );
//Checking if file exist
if( inFile && outFile )
{
//temp valarable to store each line
std::string mystring;
//Loop through each line
while (getline(inFile, mystring))
{
//... Call Your Business Logic functions here, ( make use of pass by refernce or return to get back the string )
outFile << mystring.c_str() << "\n";
}
//closing file after completing
inFile.close();
outFile.close();
}
else
{
std::cout << "Could not open File to read or write"<<std::endl;
}
return 0;
}

How to replace value in CSV file

I have CSV file build like this:
1;name;2;5;
2;diff_name;3;5;
And I would like to be able to replace the 5 with 2 before reading the next line.
So I am reading the file:
file>>number1;
file.ignore( numeric_limits < streamsize >::max(), ';' );
file>>data;
and so on. And I was trying to write it this way:
long pos = plik.tellp();
plik.seekp (pos-2);
plik<<other_number;
But it breaks the file. I don't know how but it's not reliable. the pos somehow depends on the file lenght and I can't make it work every time (with different valuse in file) this way. Is there some other way to replace the value here? Is there an easy way?
As said by Joachim Pileborg in a comment, you can't really (and simply) directly replace in the file. The solution is to write in an other file. If your first file is enough small, you can use your memory in place of a second file, and write the result in the first file.
My code :
#include <fstream>
#include <iostream>
using namespace std;
int main(){
ifstream ifile("file.csv"); //First file
ofstream ofile("filenew.csv"); //File with replaced fields
char s[100];
string temp;//useful for the replacement
int count=0;//fields counter (useful for replacement)
while(ifile.good()){
ifile.getline(s, 100, ';'); //We read the file field by field
count++;
if(ifile.good()){
if(count==3){ //The third field is stored in a temp variable
temp = s;
}
else if(count==4){//And we put the fourth field before the third
ofile << s;
ofile << ';';
ofile << temp;
ofile << ';';
count=0;
}
else{
if(count==5)count=0;
ofile << s;
ofile << ';';
}
}
}
}

Whats the best way to get text from a .txt file to a vector<string>? C++

I asked a question yesterday but i didn't manage to do anything. I am using visual studio with marmalade and im already studying c++ but i need to get things done here so i asking for i little help and patience of you guys.
I got a few responses like
std::ifstream inp("restrict_words.txt");
std::istream_iterator<std::string> inp_it(inp), inp_eof;
std::vector<std::string> words(inp_it, inp_eof);
// words now has ever whitespace separated string
// from the input file as a vector entry
for (auto s : words)
std::cout << s << '\n';
and
std::ifstream ist("restrict_words.txt");
std::string word;
std::vector<std::string> readWords;
while(ist >> word)
readWords.push_back(word);
//test
for(unsigned i = 0; i != readWords.size(); ++i)
std::cout << readWords.at(i) << '\n';
Its such a easy thing and im not managing to do this.
I have my KingChatFilter.app and a chat folder inside my game folder. Inside this chat folder i have this txt with 160 words in 160 different lines.
All i need to do is read this txt and after putting it on a array checking if some of this string match with the one i want so i can do other stuff.
Please someone make me understand this thanks :)
I wrote a couple of functions to match your requirements:
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
// Reads the file line by line and put all lines into words vector.
void read_to_vector(const char* file_name, vector<string> &words)
{
ifstream input(file_name);
string line;
while (getline(input, line))
{
words.push_back(line);
}
}
// Returns true if word is in words. False otherwise.
bool find_word(vector<string> &words, string word)
{
vector<string>::iterator it; // In c++11 you can change this to
// auto it;
// Using std::find from algorithm library.
it = find(words.begin(), words.end(), word);
return it != words.end(); // If the end of vector words was reached, then word was NOT found.
}
int main()
{
vector<string> words;
string target = "level";
read_to_vector("data.txt", words);
if (find_word(words, target))
cout << "Word " << target << " found" << endl;
else
cout << "Word " << target << " not found" << endl;
return 0;
}
following is working code i used to read file content line by line. One difference is maybe that u do not check if opening the file did succeed. If it does not, there come at least two main reasons to mind:
the file cannot be found at the specified path
the file is already opened by someone else
;
std::string fileNameWithPath = "..\\myFolder\\myfile.txt";
std::ifstream inputFile;
std::vector< std::string > fileContent;
inputFile.open( fileNameWithPath.c_str(), std::ios::in | std::ios::binary );
if( inputFile.is_open() )
{
std::string line;
while( std::getline( testDataFile, line ) )
{
inputFile.push_back( line );
}
}
inputFile.close();

getline() function in C++ does not work

i wrote a code in C++ where it opens a .txt file and reads its contents, think of it as a (MAC address database), each mac address is delimited by a (.), my problem is after i search the file for total number of lines , iam unable to return the pointer to the initial position of the file in here i use seekg() and tellg() to manipulate the pointer to the file.
here is the code:
#include <iostream>
#include <fstream>
#include <conio.h>
using namespace std;
int main ()
{
int i = 0;
string str1;
ifstream file;
file.open ("C:\\Users\\...\\Desktop\\MAC.txt");
//this section calculates the no. of lines
while (!file.eof() )
{
getline (file,str1);
for (int z =0 ; z<=15; z++)
if (str1[z] == '.')
i++;
}
file.seekg(0,ios::beg);
getline(file,str2);
cout << "the number of lines are " << i << endl;
cout << str2 << endl;
file.close();
getchar();
return 0;
}
and here is the contents of the MAC.txt file:
0090-d0f5-723a.
0090-d0f2-87hf.
b048-7aae-t5t5.
000e-f4e1-xxx2.
1c1d-678c-9db3.
0090-d0db-f923.
d85d-4cd3-a238.
1c1d-678c-235d.
here the the output of the code is supposed to be the first MAC address but it returns the last one .
file.seekg(0,ios::end);
I believe you wanted file.seekg(0,ios::beg); here.
Zero offset from the end (ios::end) is the end of the file. The read fails and you're left with the last value you read in the buffer.
Also, once you've reached eof, you should manually reset it with file.clear(); before you seek:
file.clear();
file.seekg(0,ios::beg);
getline(file,str2);
The error would have been easier to catch if you checked for errors when you perform file operations. See Kerrek SB's answer for examples.
Your code is making all sorts of mistakes. You never check any error states!
This is how it should go:
std::ifstream file("C:\\Users\\...\\Desktop\\MAC.txt");
for (std::string line; std::getline(file, line); )
// the loop exits when "file" is in an error state
{
/* whatever condition */ i++;
}
file.clear(); // reset error state
file.seekg(0, std::ios::beg); // rewind
std::string firstline;
if (!(std::getline(file, firstline)) { /* error */ }
std::cout << "The first line is: " << firstline << "\n";

Reading char from file in c++

I have created a file hangman_word_collection.txt and stored all the content of file into the string line.
Now I want to use the line string in my program but line[0] is not having any value into it or I don't know if it have something in it.
I am new to this please help.
Here is the code:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
string line;
ifstream myfile ("hangman_word_collection.txt");
if (myfile.is_open()) {
while (myfile.good()) {
getline (myfile,line);
cout << line << endl;
}
}
for(int i=0; i <= 79; i++) {
cout << "\n" << i;
cout << ":" << line[i];
}
return 0;
}
And the output:
actingraringbackupcampusdacoiteasilyfabricgardenhackediceboxprimeralwaysupload.
0:
1:c
2:t
3:i
4:n
5:g
6:r
7:a
8:r
9:i
10:n
11:g
12:b
13:a
14:c
15:k
Press <RETURN> to close this window...
When getline fails on writing to your target line you are assuming it will not modify what is in that string but it is blanking the string, which internally is replacing character 0 with a null character.
The rest is undefined behaviour as you are reading characters off the end of the logical string.
To fix this issue change your code to;
string line;
ifstream myfile ("hangman_word_collection.txt");
if (myfile.is_open())
{
while (myfile.good())
{
std::string temp;
if( getline( myfile, temp ) )
{
temp.swap( line );
cout <<line<<endl;
}
}
}
Note that it is bad practice to hard-code in magic numbers like 79. If you had put line.size() instead you would have seen what size the string actually is, and there would be no undefined behaviour. You can store this in a variable outside the loop if you are worried about performance, although chances are it makes little difference.