Content of string is different from expected content [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
the task is to read an input file, store the content of the file in a string variable and perform some operations on it. I have a problem by removing all new line characters from the string. Reading the content of the file and storing it in a string variable works fine, but somehow trying to remove the new line characters doesn't work as it should.
For reading the content of the file, I just use an ifstream. The task recommends to misuse the string datatype in order to achieve fast input and output. This is done with the following lines, where file is the ifstream variable and size is the size of the file:
string buffer(size, ' ');
file.read(const_cast<char*>(buffer.data()), size);
This works perfectly fine, but if I try to remove the new line characters, the content of buffer changes somehow, see example below. I try to remove the new line characters with the following line:
buffer.erase(std::remove(buffer.begin(), buffer.end(), '\n'), buffer.end());
Example:
I have a text file with the content (no new line at the end):
line 1
line 78
line 3
I want the output to be:
line 1line 78line 3
Somehow the output is:
line 38
I really have no idea, why this is happening. Printing buffer after reading the file works perfectly fine, but after trying to remove the new line characters the output is always wrong.
I hope you can help me finding a solution.

Your file has Windows newlines \r\n. When you remove \n, you get line 1\rline 78\rline 3. \r in output is treated as caret return, i.e. move next output position to the beginning of the line. Thus line 78 rewrites line 1 and line 3 rewrites first 6 chars of line 78. You get line 38.
The simplest solution
buffer.erase(std::remove(buffer.begin(), buffer.end(), '\r'), buffer.end());
buffer.erase(std::remove(buffer.begin(), buffer.end(), '\n'), buffer.end());

Related

Attempt to compare character in string to carriage return does not work

I have some code to read a text based file format in that it checks for empty line with:
line == ""
where line is a string that receives a text line obtained through getline.
It worked with my own text based file format, but it did not work with another text based file format (not mine)
I opened the file with gedit and saw nothing. More and less utilities also did not show anything. Then I tried vi and it showed:
^M on all these lines that seemed empty until now (a screenshot of it is here: .
Did some research and it seems that opening the file in text mode, all I needed to do was to compare it to '\n'. So I wrote the line:
if (line[0] == '^M' || line[0] == '\n')
break;
to end a while loop where this "if" is inside, but it did not work. What do I need to do?
As you have already surmised, those ^Ms are vi's way of showing you that there are carriage return characters at the end of each line. The file probably originated on Windows.
As other commentators have mentioned, the way a carriage return character is represented in C / C++ is '\r', and the line endings in that particular file will almost certainly actually be \r\n (CRLF).
So, now you know how it all works you have some code to write. getline will remove the \n but you'll have to strip the \r (if there is one) off the end of the line yourself. Go to it.

Loading a file with the LoadFromFile () function with a newline

I load the text file .txt using the LoadFromFile() function, and the text in the middle of the line is marked with a newline '\n'.
The LoadFromFile() function treats this character as a new line and divides the line in that place by creating a new line.
In the Windows system Note the text looks like this: **Ala has ace**
The program that loads this file looks different:
plik->LoadFromFile( path, TEncoding::ASCII);
for( short int i = 0; i < plik->Count; ++i )
Memo1->Lines->Add( plik->Strings[i] );
In Memo1 the text looks like this:
**Ala**
**has ace**
Can I remove the '\n' character to make the entire line and how?
I answered this same question on the Embarcadero forums earlier today, but I will answer it here, too.
plik is a TStringList (according to the other discussion), so its LoadFrom...() method treats bare-CR, bare-LF, and CRLF line breaks equally when the TStrings::LineBreak property matches the RTL's global sLineBreak constant. If the LineBreak property does not match sLineBreak, then TStrings only splits on line breaks that match its LineBreak property.
Since the RTL's sLineBreak constant is CRLF on Windows, and you don't
want to split on bare-LF line breaks, you are going to have to parse
the file data manually, not use TStrings::LoadFromFile() at all.
For instance, you could read the whole file into a System::String using the System::Classes::TStreamReader::ReadToEnd() or System::Ioutils::TFile::ReadAllText() method (TStreamReader and TFile both have methods for reading lines, but they both treat all three forms of line break equally), and then parse that String to extract CRLF-delimited substrings while ignoring any bare-LF characters.
Ideally, you would load a file into a TMemo by using its own LoadFromFile() method. But, in this situation, that will not work, either, because TMemo normalizes all three forms of line breaks to CRLF before passing the data to the Win32 API, so that is not useful to you.

C++ append to existing file [duplicate]

This question already has answers here:
How to write to middle of a file in C++?
(3 answers)
Closed 6 years ago.
I'm trying to take data from multiple files and append them into one file using fstream, however whenever I try to output to an existing file using
std::ofstream Out("mushroom.csv", std::ofstream::app);
it outputs to the end of the file, I want it to append to the same line, for example if this is the previous file:
1,2,3,4,5,6,7
8,9,10,11,12,13
I want it to become:
1,2,3,4,5,6,7,a,b,c
8,9,10,11,12,13,c,d,e
You can't. Files don't really have lines, they just store a bunch of characters/binary data. When you have
1,2,3,4,5
6,7,8,9,0
It only looks that was because there is an invisible character in there that tells it to write the second line to the second line. The actual data in the file is
1,2,3,4,5\n6,7,8,9,0
So you can see then end of the file is after the 0 and to get after the 5 you would need to seek into the middle of the file.
The way you can get around this is to read each line of the file into some container and then add your data to the end of each line. Then you would write that whole thing back o the file replacing the original contents.

Read in a certain line only? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm making a program to read in a configuration file and I only want to read certain lines. Example:
config.txt:
This is a test configuration text file
It isn't supposed to read this line or the line above it
Read this line, but not the white space above or below it
Don't read this line or the white space above or below it
Read this line, but not the white space above or below it
I'm using your basic I/O:
FILE *File;
File = fopen("config.txt", "r");
You can mark lines you don't want to read with some character or a number, so whenever input stream reads it, you can skip it.
0 This is a test configuration text file
0 It isn't supposed to read this line or the line above it
1 Read this line, but not the white space above or below it
0 Don't read this line or the white space above or below it
0 Read this line, but not the white space above or below it
Then check value in first place of every line and skip it/ read it.
Or use something like multiline comments in C /* commented out */ check for opening character and skip everything before closing character.

c++ write to the beginning of current line of file [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I created a ofstream file.
How can I write to the beginning of current line on my file?
For example: I write:
a b c d e f
and now I want to add to the beginning the number of my letters (6) like this:
6 a b c d e f
You have to read the whole file in a byte array.
Then you write your "prefix" followed by you write the byte array to a tmp file.
Finally you have to delete the original file and rename the tmp file.
If you want to write at the beginning of an arbitrary line then you should read the whole file in an array of arrays of bytes, append your prefix to the line you want to edit and finally overwrite the original file.
HINT:-
If it is a text file then the best solution would be to flush the old contents into a temporary location, write what you need and append the old contents
Files are pretty static and don't support adding characters anywhere except at the end. If you need to add characters elsewhere, you need to rewrite the file. Also, files don't really have a concept of lines.
What you could do is recording the position of the file at the beginning of the line (using file.tellp()), write a couple of placeholders (e.g., spaces), and then the rest of the line. Once the line is complete, you'd reposition the write position (using file.seekp()) and overwrite some of the placeholders.
Personally, I wouldn't do anything like that! Instead, I would format the line into a std::ostringstream and, once completed write the line start information followed by the firmatted line (obtained from the std::ostringstream using str()). Well, ideally I'd write the information in one sequence directly to the file if it is readily available.
Files are essentially a stream of bytes that start at a specific location. The only way to insert new data in the front (or in the middle) of a file is to move the data that is after it. Since you are expecting to rewrite the first line, that would mean you would need to read the entire file, prepend your new data, and write out the entire (new) file over the existing one. You can do this with a single std::fstream object, but you will need to reset the file cursor to the beginning after you read the file. It would be more clear to read the file in using an std::ifstream object and then to overwrite the file with an std::ofstream object.
I have on my code:
file << args;
-->here I want to add to the beggining of this line a new argument.. (This argument has information of args But I must write args and after I have the information for the argument)
file << endl;