Basically, I'm trying to stream in a text file and stream out THE SAME information to another text file.
However, it's giving me weird new lines.
Example txt to test:
testing this is a test to see if this actually works
hopefully!
test
test
test
This is the output it gives me after testing:
testing this is a test to see if this actually works
hopefully!test
test
test
I want the output to be the same as the input. But I'm not sure what I'm doing wrong. Been stuck on this for a few hours now, lol.
Here is my code:
string input, name, content;
cout << "Enter input name and extension (Example: hi.txt)\n";
cin >> input;
ifstream file (input.c_str());
if (file.is_open()) {
cout << "Enter output name and extension (Example: hi2.txt)\n";
cin >> name;
ofstream output(name.c_str());
while (getline(file, content)) {
output << content;
if (content == "") {
output << "\n";
}
}
}
std::getline ignores the delimiter, which by default is \n when it reads a line. So, when it reads
testing this is a test to see if this actually works\n
content will actually be
testing this is a test to see if this actually works
Note the missing newline. That's why there is one new line missing after every line :)
You have to add that discarded delimiter:
output << content << '\n'; //Adds the discarded '\n' delimiter
Related
I am currently writing a program that automates a game I play. I am doing this as a side project and I am currently stuck on a file input/output issue. All the text information stored inside the json file gets fully deleted once I finish running the program. I am trying to find certain phrase in a json file and then replace it with a different one. I made multiple functions to help assist me in doing this. I am utilizing one function to find the line specified within the file, and then another line to replace the string I located with a string I made, based on splicing using a mixture of hard-coded text and a user inputted string. I am aware that I am using cin >> rather than getline and using strings in c++ but I promise you that is not the issue at hand here. The problem is that my entire file's content is being deleted and I am not quite sure why. I will link my code below with a picture of the output and hopefully someone can help me out here because I am genuinely confused, especially since this seems like such a rudimentary task. I took out segments of the code because the entire project is pretty extensive, if there is anything missing down below or anything is unclear please let me know in the comments.
string FindFullLine(std::ifstream& file, unsigned int num){
std::string s;
for (int i = 1; i <= num; i++)
std::getline(file, s);
return s;
}
bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
^^ separate functions that are being used in this small piece of code below
string champo = " \"mainChamp\": ";
string apo = "\",";
string champ, ban, gamemode, newchamp;
cout << "What champion would you like to pick? " << endl;
cin >> champ; //getline doesnt work; cin is not causing the issue
cout << "\nWhat champion would you like to ban? " << endl;
cin >> ban;
cout << "\nWhat gamemode would you like to pick? " << endl;
cin >> gamemode;
newchamp = " \"mainChamp\": \"";
newchamp += champ;
newchamp.append(apo);
ifstream yuumi ("C:\\forfuncoding\\bot\\Yuumi Bot Extension Fix\\bot\\config.json"); //opening file stream for input
ofstream yuumi1 ("C:\\forfuncoding\\bot\\Yuumi Bot Extension Fix\\bot\\config.json"); //opening file stream for output
if(!yuumi || !yuumi1){
cout << "Error opening up files! " << endl;
exit(0);
}
string s = FindFullLine(yuumi, 2);
string temps;
string strTemp;
temps = s; //temporary val to store s
cout << s;
replace(s, s , newchamp); //first parameter is where new string is stored, second param is the old string and third param is what old string is being replaced by new string
cout << s;
while(yuumi >> strTemp)
{
if(strTemp == temps){
cout << s;
strTemp = s;
}
yuumi1 << strTemp;
}
yuumi.close(); //closes file for output
yuumi1.close(); //closes file for input
exit(0); //just for testing purposes
I have tried changing many values by passing them by reference/not by reference, I have tried using fstream with ios::out and ios::in, I have tried using getline, I have tried moving the logic around; making sure all the variables are scoped correctly. At first glance I thought the issue was in the replace function since it returns a bool but after further inspection it also works as is. Originally, the FindFullLine function was made for fstream, but I changed it to ifstream in the parameters, I don't believe that would change much however. I also tried getting rid of the ifstream and ofstream.close(); functions. I have tried practically everything I can think of.Down below is a screenshot of the format I was attempting to copy.
format of text in json file i was copying
I believe I formatted everything correctly in my code in order to match exactly what is happening in the text file. But when I run the code, everything disappears and the text file is blank. Linked down below is the output that I get, there is a cout << statement after the replace function is ran to ensure that everything is working as intended, and from the output's point of view, everything is working correctly.
output from console
My problem in a larger project is that std::getline() returns an empty string. Here's my code snippet:
int main() {
std::ifstream reading_file;
reading_file.open("smalldata-n.txt", std::ios::in);
std::string line;
std::getline(reading_file, line);
std::cout << "1. first line is: " << line << std::endl;
return 0;
}
The first line has very important information for the rest of the code.
At first, I thought maybe the problem is from the data format but when using another simple text file I encounter the same problem again.
I can't see what I have missed and it looks fine according to other samples on the web.
So I have a function which is supposed to read 6 variables in each line from a file, and then show them to console, the problem is the string RenterName if it includes a space, the code doesn't work properly. This is my code:
...
void displayRentersInformations() {
int RenterID, Fine;
string RenterName, FlatNumber, Status;
ifstream in;
in.open("RentersInformation.txt");
if (!in) {
cout << "There is no information to be shown! \n";
}
else {
while (in >> RenterID >> RenterName >> FlatNumber >> Fine >> Status) {
cout << RenterID << RenterName << FlatNumber << Fine << Status << endl;
}
}
in.close();
}
this is an example of the text from the file:
223456000 Sami Ahmed A7 6000 Paid
so Sami Ahmed should be stored as string inside RenterName but the space between them is making the problem, I tried using getline but It didn't work or I just didn't use it the right way, how to solve this problem?
the problem is the string RenterName if it includes a space, the code doesn't work properly.
No, the code still works the way it suppose to work. Consider 2 variables a and b and the following line in a file:
Hello from file
Now doing this:
in >> a >> b
will read "Hello" and "from" and NOT "Hello from" and "file" or "Hello" and "from file".
If you want a variable to contain whitespaces you need to change the file format. You could for example separate using a delimiter:
Hello, from file
and then use std::getline() to read the entire line an then split using the delimiter.
suppose I have a text file that have text data like:
I am reading this file in c++ like,
ifstream file("book_inventory.txt");
string content;
int i=0;
while(file >> content) {
cout << content << ' ';
}
but it display all output on a single line without showing any new line .
Read the whole line using e.g. std::getline then use a std::istringstream to parse out first the three numbers. Then it gets a little harder. If the name (like e.g. "James Pilgrim") is always two "words" then you can use normal input operator >> to get the names, and then std::getline again to get the last part.
If the name can be one, two or more words, then it's actually impossible to say when the person names ends and the title begins.
On the other hand, if you don't want to actually parse the contents, and just print the lines then just read line by line using std::getline, and remember to print a newline.
You can try the below code to read a file line by line as it is or using endl instead of ' ' in your code
ifstream myfile("book_inventory.txt");
string line;
if (myfile.is_open())
{
while (getline(myfile, line))
{
cout << line << '\n';
}
myfile.close();
}
This code always prints the last line of the file. I expected it to print all the text, one line at a time, from the file. Any idea why it doesn't work?
string filename;
cout << "File to read: ";
cin >> filename;
ifstream afile;
afile.open(filename.c_str());
string line;
while(!afile.eof()) {
getline(afile, line);
cout << line;
}
afile.close();
Trying it this way does the same thing:
for (string line; getline(afile, line);) {
cout << line;
}
Maybe this is an issue with my terminal? This works...
for (string line; getline(afile, line);) {
cout << line << endl;
}
The problem is that only the last line is printed. Correct?
I suggest that you add std::endl in your while loop. It can make the issue more clear. Sometimes the output can be confusing.
You can also check the line-delimiting character in your input file. '\n' is the default delimiter for getline. If a different character is used, specify it as getline's 3rd parameter.
From cplusplus.com:
If the delimiter is found, it is extracted and discarded, i.e. it is
not stored and the next input operation will begin after it.
Since your original code snippet doesn't insert any extra newlines itself, there is nothing making the output to the terminal go to the next line. When the output runs out of horizontal space what happens next is up to the terminal. I'm not sure what terminal you're using but in your case, it just wraps the cursor back to the first character on that line without a linefeed. On a windows command shell, it just wraps around to the next line.
Also note that:
while(!afile.eof()) {
getline(afile, line);
cout << line;
}
is a common antipattern. As already pointed out, more appropriate would be:
while(getline(afile, line)) {
cout << line << '\n';
}
The file stream only becomes false after you've reached eof and try to read from it.