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;
}
Related
I'm having trouble in understanding some part of this code I've found online, its goal is to print ASCII art from a .txt file. To be more accurate, I'm having trouble in undesrstanding the while loop in line 28 which is part of the string function "getFileContents". What's the meaning of 'TempLine'?
#include <iostream>
#include <fstream>
#include <string>
std::string getFileContents (std::ifstream&); //Gets file contents
int main(int argc, char *argv[])
{
std::ifstream Reader ("File1.txt"); //Open file
std::string Art = getFileContents (Reader); //Get file
std::cout << Art << std::endl; //Print it to the screen
Reader.close (); //Close file
return 0;
}
std::string getFileContents (std::ifstream& File)
{
std::string Lines = ""; //All lines
if (File) //Check if everything is good
{
while (File.good ())
{
std::string TempLine; //Temp line
std::getline (File , TempLine); //Get temp line
TempLine += "\n"; //Add newline character
Lines += TempLine; //Add newline
}
return Lines;
}
else //Return error
{
return "ERROR File does not exist.";
}
}
If you take a look at std::getline(), you can see that the string parameter is passed by non-const reference. This means that the string can (and is) edited by the std::getline() function. So line by line:
// Loop until the file stream cannot read any more input.
while (File.good ())
{
// Create a new, empty string called `TempLine`
std::string TempLine;
// Read a line from `File`, and write it into TempLine.
std::getline (File , TempLine);
// Add a newline character at the end of the string.
TempLine += "\n";
// Add the line we just read from the file to the `Lines` string,
// which holds the full file contents.
Lines += TempLine; //Add newline
// Repeat until all lines have been read from the file (or the file
// becomes otherwise unreadable).
}
The reason TempLine is needed is because std::getline() needs something to read the file content into, and if we passed Lines directly to the function, we'd only ever return the last line of the file (the previous lines would always get overwritten in the string).
I am looking for a way to search for a specific character in a text file and add a new-line after every ;
It's a pretty big document (2,7MB) if that matters.
You can't insert new characters into the middle of an existing file, only append to the end. You will have to create a new file, copying characters from the old file to the new file, inserting new characters as needed. For example:
#include <string>
#include <fstream>
int main()
{
std::ifstream inFile("input.txt");
if (!inFile.is_open())
{
std::cerr << "Failed to open input file";
return 1;
}
std::ofstream outFile("output.txt");
if (!outFile.is_open())
{
std::cerr << "Failed to create output file";
return 1;
}
std::string line;
while (std::getline(inFile, line, ';'))
{
outFile << line;
if (!inFile.eof())
outFile << ";\n";
}
return 0;
}
As SomeProgrammerdude points out in the comments, inserting into an existing file isn't really feasible and one of your options is to read it all into a single std::string and write back into the same text file.
Here is an example implementation. We read a charter at a time and check if it is a semicolon, and add a newline after every semicolon. Notice the reserve part, although advised, it is not mandatory:
#include <string>
#include <fstream>
#include <stdexcept>
int main()
{
std::fstream f("test.txt", std::ios::in);
if (!f.is_open()) {
throw std::runtime_error("Failed to open file");
}
std::string contents;
contents.reserve(10000); // reserve some space for better efficiency
char ch;
while (f.get(ch)) {
contents.push_back(ch);
if (ch == ';')
contents.push_back('\n');
}
f.close();
f.open("test.txt", std::ios::out);
if (!f.is_open()) {
throw std::runtime_error("Failed to open file");
}
f << contents;
f.close();
return 0;
}
Input:
line line line line; line line line line; line line line; line line
Output:
line line line line;
line line line line;
line line line;
line line
Note the leading spaces before lines. This is because we appended '\n' after every ';', did not replace the spaces.
I am trying to open a file and parse a file with separate functions.
when i parse the file, i want to read each line in my input file and i want to ignore any punctuation and make everything lowercase so that i can then print it out to a separate file into strings with no spaces or punctuation.
i have tried to implement it but i cannot figure out what i am doing wrong. I am not getting an error but my output is not correct.
this is my code:
#include <iostream>
#include <fstream>
#include <ostream>
#include <sstream>
#include <string>
using namespace std;
void processFile();
void parseFile(ifstream&, ofstream&);
int main()
{
//call function to open file and process
cout << "processing file" << endl;
processFile();
return 0;
}
void processFile()
{
string newString;
ifstream inFile;
ofstream outFile;
cout << "opening files" << endl;
// open files
inFile.open("inFile.txt");
outFile.open("outFile.txt");
cout << "parsing file" << endl;
//parse file for capitalization & punctuation
parseFile(inFile, outFile);
//close files
outFile.close();
inFile.close();
}
void parseFile(ifstream &inFile, ofstream &outFile)
{
//create and initialize variables
string newString;;
int i = 0;
if(!inFile)
{
cout << "ERROR!!! Cannot read file.";
}
else
{
do
{
//read each line in the input file until EOF
getline(inFile, newString, '\n');
//parse each string for punctuation
while(newString[i])
{
if(isalpha(newString[i])) //check each char in each
//string for punctuation
{
if(isupper(newString[i])) //check each string for
//capitalization
{
newString[i] = tolower(newString[i]); //convert
//string to
//lower case
}
outFile << newString[i]; //output each line to file
cout << newString[i];
}
i++;
if(newString[i] == '\n')
break;
}
} while(!inFile.eof());
}
}
this is my input:
racecar
RACEcar
rotator
rotor
civic
Red rum, sir, is murder!
Rats live on no evil star.
Neil, a trap! Sid is part alien!
Step on no pets.
Dammit, I’m mad!
my expected output is everything in the input printed in lowercase, without punctuation and spaces
this is my actual output:
racecarsirismurderraliena
You will need to initialize i after getline() . This is because each call of getline() will cause each line of data read from input file be overwritten (not appended) to the newString.
do
{
//read each line in the input file until EOF
getline(inFile, newString, '\n');
i = 0; // <== initialize 'i' to zero
//parse each string for punctuation
while(newString[i])
{
You need to reinitialize i after each call to getline(), otherwise it will continue at the offset where the previous string ended. getline() overwrites newString every time it's called.
do
{
//read each line in the input file until EOF
getline(inFile, newString, '\n');
i = 0;
//parse each string for punctuation
If you compare your input with your output it makes sense.
The first string "racecar" is parsed without problem. Now i is 7.
The next 4 calls to getline() get strings that are shorter than 7 so you get no new output in outFile.txt.
The call to getline() after that gets "Red rum, sir, is murder!", starting from 7 you get "sirismurder" and i is now 24.
The next call to getline() gets "Rats live on no evil star.", starting from 24 you get "r" and i is is now 26
The last call to getline() gets "Neil, a trap! Sid is part alien!", starting from 26 you get "alien".
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.
How can I make my std::fstream object start reading a text file from the second line?
Use getline() to read the first line, then begin reading the rest of the stream.
ifstream stream("filename.txt");
string dummyLine;
getline(stream, dummyLine);
// Begin reading your stream here
while (stream)
...
(Changed to std::getline (thanks dalle.myopenid.com))
You could use the ignore feature of the stream:
ifstream stream("filename.txt");
// Get and drop a line
stream.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
// Get and store a line for processing.
// std::getline() has a third parameter the defaults to '\n' as the line
// delimiter.
std::string line;
std::getline(stream,line);
std::string word;
stream >> word; // Reads one space separated word from the stream.
A common mistake for reading a file:
while( someStream.good() ) // !someStream.eof()
{
getline( someStream, line );
cout << line << endl;
}
This fails because: When reading the last line it does not read the EOF marker. So the stream is still good, but there is no more data left in the stream to read. So the loop is re-entered. std::getline() then attempts to read another line from someStream and fails, but still write a line to std::cout.
Simple solution:
while( someStream ) // Same as someStream.good()
{
getline( someStream, line );
if (someStream) // streams when used in a boolean context are converted to a type that is usable in that context. If the stream is in a good state the object returned can be used as true
{
// Only write to cout if the getline did not fail.
cout << line << endl;
}
}
Correct Solution:
while(getline( someStream, line ))
{
// Loop only entered if reading a line from somestream is OK.
// Note: getline() returns a stream reference. This is automatically cast
// to boolean for the test. streams have a cast to bool operator that checks
// good()
cout << line << endl;
}
The more efficient way is ignoring strings with std::istream::ignore
for (int currLineNumber = 0; currLineNumber < startLineNumber; ++currLineNumber){
if (addressesFile.ignore(numeric_limits<streamsize>::max(), addressesFile.widen('\n'))){
//just skipping the line
} else
return HandleReadingLineError(addressesFile, currLineNumber);
}
HandleReadingLineError is not standart but hand-made, of course.
The first parameter is maximum number of characters to extract. If this is exactly numeric_limits::max(), there is no limit:
Link at cplusplus.com: std::istream::ignore
If you are going to skip a lot of lines you definitely should use it instead of getline: when i needed to skip 100000 lines in my file it took about a second in opposite to 22 seconds with getline.
Call getline() once to throw away the first line
There are other methods, but the problem is this, you don't know how long the first line will be do you? So you can't skip it till you know where that first '\n' is. If however you did know how long the first line was going to be, you could simply seek past it, then begin reading, this would be faster.
So to do it the first way would look something like:
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
// Open your file
ifstream someStream( "textFile.txt" );
// Set up a place to store our data read from the file
string line;
// Read and throw away the first line simply by doing
// nothing with it and reading again
getline( someStream, line );
// Now begin your useful code
while( !someStream.eof() ) {
// This will just over write the first line read
getline( someStream, line );
cout << line << endl;
}
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string textString;
string anotherString;
ifstream textFile;
textFile.open("TextFile.txt");
if (textFile.is_open()) {
while (getline(textFile, textString)){
anotherString = anotherString + textString;
}
}
std::cout << anotherString;
textFile.close();
return 0;
}
this code can read file from your specified line from file but you have to make file in file explorer before hand my file name is "temp" code is given below
https://i.stack.imgur.com/OTrsj.png
hope this can help
You can use ignore function as follow:
fstream dataFile("file.txt");
dataFile.ignore(1, '\n'); // ignore one line
#include <fstream>
#include <iostream>
using namespace std;
int main ()
{
char buffer[256];
ifstream myfile ("test.txt");
// first line
myfile.getline (buffer,100);
// the rest
while (! myfile.eof() )
{
myfile.getline (buffer,100);
cout << buffer << endl;
}
return 0;
}