How to Write Std::String to File

How to write std::string to file?

You're currently writing the binary data in the string-object to your file. This binary data will probably only consist of a pointer to the actual data, and an integer representing the length of the string.

If you want to write to a text file, the best way to do this would probably be with an ofstream, an "out-file-stream". It behaves exactly like std::cout, but the output is written to a file.

The following example reads one string from stdin, and then writes this string to the file output.txt.

#include <fstream>
#include <string>
#include <iostream>

int main()
{
std::string input;
std::cin >> input;
std::ofstream out("output.txt");
out << input;
out.close();
return 0;
}

Note that out.close() isn't strictly neccessary here: the deconstructor of ofstream can handle this for us as soon as out goes out of scope.

For more information, see the C++-reference: http://cplusplus.com/reference/fstream/ofstream/ofstream/

Now if you need to write to a file in binary form, you should do this using the actual data in the string. The easiest way to acquire this data would be using string::c_str(). So you could use:

write.write( studentPassword.c_str(), sizeof(char)*studentPassword.size() );

Is there a way I can write a string into a FILE?

If you are just trying to print out to a file the contents of a string, using fwrite, then you need to do something like the following

std::string str = randomString();

if ( file ) {
fwrite( str.c_str(), sizeof( char ), str.size(), file );
fclose( file );
}

Since fwrite expects the first parameter to be void *, an std::string is not compatible; however, a char * is. By calling .c_str() on the string, you would have a char * to work with. The second parameter is the size of the type, which for a std::string is char, so sizeof( char ) gives the size (which is 1). The third parameter is the count (number of characters to write), which can easily be gotten from str.size().

What is the preferred way to write string to file in C++, use '+' or several ' '?

I wrote a small program that tries both methods, the first version, using << seems to be faster. In any case, the usage of std::endl inhibits performance significantly, so I've changed it to use \n.

#include <iostream>
#include <fstream>
#include <chrono>

int main () {
unsigned int iterations = 1'000'000;
std::string str1 = "Prefix string";

std::ofstream myfile;
myfile.open("example.txt");

auto start = std::chrono::high_resolution_clock::now();
for (int i=0; i < iterations; i++) {
myfile << str1 << " " << 10 << "Text" << "\n";
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = stop - start;
std::cout << "Duration: " << duration.count() << std::endl;

std::ofstream myfile2;
myfile2.open("example2.txt");

start = std::chrono::high_resolution_clock::now();
for (int i=0; i < iterations; i++) {
myfile2 << str1 + " " + std::to_string(10) + "Text" << "\n";
}
stop = std::chrono::high_resolution_clock::now();
duration = stop - start;
std::cout << "Duration: " << duration.count() << std::endl;

myfile.close();
return 0;
}

And the output on my machine:

Duration: 91549609
Duration: 216557352

std::ofstream not able to write std::string to file

So, solution:
A missing header.

#include <iostream> 

was already there, but not

#include <fstream>

How to write string to file?

write! is a macro, similar to print!. It expects 2 or more arguments, the first being a writer, the second a format string (which must be a string literal) and after that zero or more expressions which will be placed into the placeholders in the format string.

So, you could combine both your last two lines like this:

fn main() -> Result<(), Error> {
let path = "results.txt";
let mut output = File::create(path)?;
let line = "hello";
write!(output, "{}", line);
}

Other methods to write to a Writer include calling std::io::Write::write_all, or to write a slice into a file directly you can use std::fs::write.

Another thing to note: the print! macro does not return the output in a string, it prints the output to stdout. If you want to get the formatted result in a string, use the format! macro:

let my_string = format!("Hello {}", "world");

C++, write from file into map

You are telling getline() to read until a '\0' (nul) character is encountered, but there is no such character in your file, so the entire file gets read into the string on the 1st call, and then you extract only the 1st set of values from the string, discarding the rest of the data.

To read the file line-by-line, you need to change the 3rd parameter of getline() to '\n' instead:

while (std::getline(frequencieFile, line, '\n'))

Or, just drop the 3rd parameter entirely since '\n' is the default delimiter:

while (std::getline(frequencieFile, line))

How to write a String to file?

Your issue is that the file you opened is opened in read-only mode.

As @Herohtar correctly pointed out, from the documentation of File::open():

Attempts to open a file in read-only mode.

What you are trying to do requires read & write mode. There is no pre-made function for that, so you need to build your own using OpenOptions:

//Import
use std::fs::OpenOptions;
use std::io::*;

//Mainfunction
fn main() {
//Programm startet hier | program starts here
println!("Program started...");

// Lesen des Files, createn des Buffers | reading file createing buffer
let mut testfile = OpenOptions::new()
.read(true)
.write(true)
.open("test_0.txt")
.unwrap();
let mut teststring = String::from("lol");

//Vom File auf den Buffer schreiben | writing from file to buffer
testfile.read_to_string(&mut teststring).unwrap();

//Buffer ausgeben | print to buffer
println!("teststring: {}", teststring);

// Neue Variable deklarieren | declare new variable
let msg = String::from("Writetest tralalalal.");

// msg an ursprünglichen String anhängen | append msg to string
teststring.push_str(&msg);
println!("teststring: {}", teststring);

// Neuen String nach File schreiben | write new sting to file
let eg = testfile.write_all(teststring.as_bytes());
match eg {
Ok(()) => println!("OK"),
Err(e) => println!("{:?}", e),
}
println!("Fertig")
}

The rest of your code is pretty much fine.

The only nitpick I have is that testfile.write_all(&teststring.as_bytes()) doesn't make much sense, because as_bytes() already returns a reference, so I removed the & from it.

C++: writing strings to file

In several cases I found that C++ I/O streams tend to be slower than C <stdio.h> FILE*.

I had a confirmation also in the following test:

#define _CRT_SECURE_NO_WARNINGS // for stupid fopen_s warning
#include <stdio.h>
#include <exception>
#include <fstream>
#include <iostream>
#include <ostream>
#include <stdexcept>
#include <string>
#include <vector>
#include <windows.h>
using namespace std;

long long Counter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return li.QuadPart;
}

long long Frequency()
{
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
return li.QuadPart;
}

void PrintTime(long long start, long long finish, const char * s)
{
cout << s << ": " << (finish - start) * 1000.0 / Frequency() << " ms" << endl;
}

// RAII wrapper to FILE*
class File
{
public:
explicit File(FILE * f)
: m_file(f)
{}

~File()
{
fclose(m_file);
}

FILE* Get() const
{
return m_file;
}

bool IsOpen() const
{
return (m_file != nullptr);
}

private:
FILE* m_file;

File(const File&);
File& operator=(const File&);
};

void TestIoStream(const vector<string>& lines)
{
ofstream ofs("ofs.txt", ios_base::binary);
for(auto it = lines.begin(); it != lines.end(); ++it)
{
ofs << it->c_str();
ofs << "\n" ;
}
}

void TestStdioFile(const vector<string>& lines)
{
File file( fopen("cfile.txt", "wt") );
if (! file.IsOpen())
throw runtime_error("Can't open C FILE*.");

for(auto it = lines.begin(); it != lines.end(); ++it)
{
fputs( it->c_str(), file.Get());
fputs( "\n", file.Get());
}
}

int main()
{
static const int kExitOk = 0;
static const int kExitError = 1;
try
{
cout << "Building test lines...";
vector<string> lines;
for (int i = 0; i < 10000000; i++)
lines.push_back("Hi");
cout << "done. ";
cout << "(Count = " << lines.size() << ")" << endl;

long long start = 0;
long long finish = 0;

start = Counter();
TestIoStream(lines);
finish = Counter();
PrintTime(start, finish, "C++ I/O stream");

start = Counter();
TestStdioFile(lines);
finish = Counter();
PrintTime(start, finish, "C FILE*");

return kExitOk;
}
catch(const exception& e)
{
cerr << "\n*** ERROR: " << e.what() << endl;
return kExitError;
}
}

Compiled with VS2010 SP1 (VC10):

cl /EHsc /W4 /nologo /MT /O2 /GL test.cpp

Test result:

Building test lines...done. (Count = 10000000)
C++ I/O stream: 2892.39 ms
C FILE*: 2131.09 ms

How to portably write std::wstring to file?

Why not write the file as a binary. Just use ofstream with the std::ios::binary setting. The editor should be able to interpret it then. Don't forget the Unicode flag 0xFEFF at the beginning.
You might be better of writing with a library, try one of these:

http://www.codeproject.com/KB/files/EZUTF.aspx

http://www.gnu.org/software/libiconv/

http://utfcpp.sourceforge.net/



Related Topics



Leave a reply



Submit