How to write std::string to file? - c++

I want to write a std::string variable I am accepting from the user to a file. I tried using the write() method and it writes to the file. But when I open the file I see boxes instead of the string.
The string is only a variable length single word. Is std::string suitable for this or should I use a character array or something.
ofstream write;
std::string studentName, roll, studentPassword, filename;
public:
void studentRegister()
{
cout<<"Enter roll number"<<endl;
cin>>roll;
cout<<"Enter your name"<<endl;
cin>>studentName;
cout<<"Enter password"<<endl;
cin>>studentPassword;
filename = roll + ".txt";
write.open(filename.c_str(), ios::out | ios::binary);
write.put(ch);
write.seekp(3, ios::beg);
write.write((char *)&studentPassword, sizeof(std::string));
write.close();`
}

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() );

Assuming you're using a std::ofstream to write to file, the following snippet will write a std::string to file in human readable form:
std::ofstream file("filename");
std::string my_string = "Hello text in file\n";
file << my_string;

remove the ios::binary from your modes in your ofstream and use studentPassword.c_str() instead of (char *)&studentPassword in your write.write()

If you have fmt available:
#include <fmt/os.h>
// ...
fmt::output_file(filename).print("{}\0\0{}", ch, studentPassword);
// ...
But you are not really writing a password to a file, right?

Related

.write() not working in file handling c++ [duplicate]

I want to write a std::string variable I am accepting from the user to a file. I tried using the write() method and it writes to the file. But when I open the file I see boxes instead of the string.
The string is only a variable length single word. Is std::string suitable for this or should I use a character array or something.
ofstream write;
std::string studentName, roll, studentPassword, filename;
public:
void studentRegister()
{
cout<<"Enter roll number"<<endl;
cin>>roll;
cout<<"Enter your name"<<endl;
cin>>studentName;
cout<<"Enter password"<<endl;
cin>>studentPassword;
filename = roll + ".txt";
write.open(filename.c_str(), ios::out | ios::binary);
write.put(ch);
write.seekp(3, ios::beg);
write.write((char *)&studentPassword, sizeof(std::string));
write.close();`
}
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() );
Assuming you're using a std::ofstream to write to file, the following snippet will write a std::string to file in human readable form:
std::ofstream file("filename");
std::string my_string = "Hello text in file\n";
file << my_string;
remove the ios::binary from your modes in your ofstream and use studentPassword.c_str() instead of (char *)&studentPassword in your write.write()
If you have fmt available:
#include <fmt/os.h>
// ...
fmt::output_file(filename).print("{}\0\0{}", ch, studentPassword);
// ...
But you are not really writing a password to a file, right?

Reading binary files and fill vector c++ [duplicate]

I want to write a std::string variable I am accepting from the user to a file. I tried using the write() method and it writes to the file. But when I open the file I see boxes instead of the string.
The string is only a variable length single word. Is std::string suitable for this or should I use a character array or something.
ofstream write;
std::string studentName, roll, studentPassword, filename;
public:
void studentRegister()
{
cout<<"Enter roll number"<<endl;
cin>>roll;
cout<<"Enter your name"<<endl;
cin>>studentName;
cout<<"Enter password"<<endl;
cin>>studentPassword;
filename = roll + ".txt";
write.open(filename.c_str(), ios::out | ios::binary);
write.put(ch);
write.seekp(3, ios::beg);
write.write((char *)&studentPassword, sizeof(std::string));
write.close();`
}
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() );
Assuming you're using a std::ofstream to write to file, the following snippet will write a std::string to file in human readable form:
std::ofstream file("filename");
std::string my_string = "Hello text in file\n";
file << my_string;
remove the ios::binary from your modes in your ofstream and use studentPassword.c_str() instead of (char *)&studentPassword in your write.write()
If you have fmt available:
#include <fmt/os.h>
// ...
fmt::output_file(filename).print("{}\0\0{}", ch, studentPassword);
// ...
But you are not really writing a password to a file, right?

How to use a variable as a files name?

I've been working on a program that creates and stores information onto files. My only problem that is keeping me from going any farther is the files name. I can manually name the file but I can't use a variable (any would do: number, character anything) for the files name, and for the contents of the file. Here's the 4 lines of code that have driven me up walls for a while now:
ofstream file;
file.open ("txt.txt"); \\I can manually create names, but that's not what I'm after
file.write >> fill; \\I attempted to use a 'char' for this but it gives errors based on the "<<"
file.close();
This is my first time using this site. Sorry in advance.
You may use variables of type strings and ask the user for keyboard input to name your file and fill in contents.
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char** argv) {
string fileName;
string contents;
cout << "What would you like the file name be? : ";
cin >> fileName;
cout << "\nPlease write the contents of the file: ";
cin >> contents;
ofstream file;
file.open(fileName.c_str()); // provide the string input as the file name
if(file.is_open()){ // always check if the program sucessfully opened the file
file << contents << endl; // write the contents into the file
file.close(); // always close the file!
}
return 0;
}
Note that this program will read input from user for contents until it reaches a newline character '\n' or white space ' '. So if you write HELLO WORLD! as the input for contents, it will only read HELLO.
I'll leave how to read the entire line including whitespaces as exercise for you. I also suggest you grab a C++ book and study file input/output.
It really depends? C++11 or C++03?
First create a string:
std::string fname = "test.txt";
In C++11, you can just do:
file.open(fname);
However in C++03, you must:
file.open(fname.c_str());

Read a binary file (jpg) to a string using c++

I need to read a jpg file to a string. I want to upload this file to our server, I just find out that the API requires a string as the data of this pic. I followed the suggestions in a former question I've asked Upload pics to a server using c++ .
int main() {
ifstream fin("cloud.jpg");
ofstream fout("test.jpg");//for testing purpose, to see if the string is a right copy
ostringstream ostrm;
unsigned char tmp;
int count = 0;
while ( fin >> tmp ) {
++count;//for testing purpose
ostrm << tmp;
}
string data( ostrm.str() );
cout << count << endl;//ouput 60! Definitely not the right size
fout << string;//only 60 bytes
return 0;
}
Why it stops at 60? It's a strange character at 60, and what should I do to read the jpg to a string?
UPDATE
Almost there, but after using the suggested method, when I rewrite the string to the output file, it distorted. Find out that I should also specify that the ofstream is in binary mode by ofstream::binary. Done!
By the way what's the difference between ifstream::binary & ios::binary, is there any abbreviation for ofstream::binary?
Open the file in binary mode, otherwise it will have funny behavior, and it will handle certain non-text characters in inappropriate ways, at least on Windows.
ifstream fin("cloud.jpg", ios::binary);
Also, instead of a while loop, you can just read the whole file in one shot:
ostrm << fin.rdbuf();
You shouldn't read the file to a string because it is legal for a jpg to contain values that are 0. However in a string, the value 0 has a special meaning (it's the end of string indicator aka \0). You should instead read the file into a vector. You can do this easily like so:
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
int main(int argc, char* argv[])
{
std::ifstream ifs("C:\\Users\\Borgleader\\Documents\\Rapptz.h");
if(!ifs)
{
return -1;
}
std::vector<char> data = std::vector<char>(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
//If you really need it in a string you can initialize it the same way as the vector
std::string data2 = std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
std::for_each(data.begin(), data.end(), [](char c) { std::cout << c; });
std::cin.get();
return 0;
}
Try opening the file in binary mode:
ifstream fin("cloud.jpg", std::ios::binary);
At a guess, you were probably trying to read the file on Windows and the 61st character was probably 0x26 -- a control-Z, which (on Windows) will be treated as marking the end of the file.
As far as how to best do the reading, you end up with a choice between simplicity and speed, as demonstrated in a previous answer.

How do I copy the binary code of an executable into a new file without using a system copy command?

This is the code I have, but the file is a little smaller and doesn't execute:
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
ifstream infile(inFilename.c_str(), ios::binary);
ofstream outfile(outFilename.c_str(), ios::binary);
string line;
// Initial read
infile >> line;
outfile << line;
// Read the rest
while( infile )
{
infile >> line;
outfile << line;
}
infile.close();
outfile.close();
return 0;
}
What am I doing wrong? Is there a better way to read in the binary of an executable file and immediately write it out to another name? Any code examples?
I need to do it without a system copy in order to simulate writing to disk.
One way is to use the stream inserter for a streambuf:
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
ifstream infile(inFilename.c_str(), ios::binary);
ofstream outfile(outFilename.c_str(), ios::binary);
outfile << infile.rdbuf();
}
The stream operator>>() performs formatted input even if you open the stream in binary mode. Formatted input expects to see strings of printable characters separated by spaces, but this is not what binary files like executables consist of. You need to read the file with the stream's read() function, and write it with the output stream's write() function.
Off the top of my head: (no error checking)
EDIT: Changed to fix feof bug.
int WriteFileContentsToNewFile(string inFilename, string outFilename)
{
FILE* in = fopen(inFilename.c_str(),"rb");
FILE* out = fopen(outFilename.c_str(),"wb");
char buf[4096]; //1024 is a habit of mine. 4096 is most likely your blocksize. it could also be 2<<13 instead.
int len;
while( (len = fread(buf,1,1024,in)) > 0 )
{
fwrite(buf,1,len,out);
}
fclose(in);
fclose(out);
}
(unix) the system cp command not only copies the contents of the file, but also copies (some) of the file permissions, which include the execute bit.
Make sure your copy also sets the execute bit on the output file as appropriate.