C++ write text to file, how to multiple lines - c++

How do you write multiple lines to a file? ... This is what I have.. Also, some of the lines include text like: #import <Foundation/Foundation.h> How would I go about doing this? The code below is what I have right now..
//Creates Config.h
FILE * pFile;
char *buffer = "//Empty Header File";
char file [256];
sprintf (file , "%s/Desktop/%s/Control.h",homeDir, game_name);
pFile = fopen (file, "w+");
fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
fclose (pFile);

Since this is C++, I suggest you utilize the standard IOStreams library and use the concrete file stream classes std::ifstream and std::ofstream for handling files. They implement RAII to handle the closing of the file, and use built in operators and the read()/write() member functions to perform formatted and unformatted I/O respectively. Moreover, they blend well together with the use of std::basic_string, the standard C++ string class.
With that said, if we implement this in C++ correctly, it should look like this:
std::string path = "/Desktop/";
std::string filename = homeDir + path + game_name + "/Control.h";
std::ofstream file(filename, std::ios_base::app);
This handles opening the file, but as you say you wish to write multiple lines to a file. Well this is simple. Just use '\n' whenever you wish to put a newline:
file << buffer << '\n';
If you give us more information about your issue, I will be able to elaborate more in my answer. But until you do, the above is sufficient.

Change to
sprintf (file , "%s/Desktop/%s/Control.h\n",homeDir, game_name);
\n - is a new-line code.

In C++ you would do it like this:
ofstream fout("someplace/Control.h");
fout << "a line of text" << endl;
fout << "another line of text" << endl;
I've left out some details like how to construct a filename and how to open a file in "append" mode, but you should try to tackle one problem at a time.

Related

How to read UTF-8 file data in C++?

I have a list of IPA (UTF-8) symbols in a text file called ipa.txt with numbers assigned to them. How do I cross reference it with a source file which is also a text file that contains a bunch of words and their corresponding IPA, to return a text file for every names with their names as their filename and inside the text file should contain their corresponding numbers of IPA.
Below is what I've tried but didn't work, only outputs were mostly 000000.
int main()
{
std::unordered_map <wchar_t, int> map;
std::wifstream file;
file.open("ipa.txt");
if (file.is_open()) {
std::cout << "opened ipa file";
}
wchar_t from;
int to;
while (file >> from >> to) {
map.insert(std::make_pair(from, to));
}
std::wifstream outfile;
outfile.open("source.txt");
if (outfile.is_open()) {
std::cout << "opened source file";
}
std::wstring id;
std::wstring name;
while (outfile >> id >> name) {
std::ofstream outputfile;
outputfile.open(id + L".txt");
for (wchar_t c : name) outputfile << map[c];
}
system("pause");
return 0;
}
I believe you are using the wrong type for c used in the iteration over name. As c is used as key for the map, and name is a wstring, you should use:
for (wchar_t c : name) outputfile << map[c];
instead of:
for (char c : name) outputfile << map[c];
Isn't it?
Hope this may help, Stefano
First thought:
map <- std::unordered_map<char, int>
open ipa.txt:
for each line in file:
map[line[0]] = line[1]
open source.txt:
for each line in file:
create and open line[0].txt:
for each char in line[1]:
write map[char] to line[0].txt
Regarding the actual C++ implementation, AFAIK utf-8 should fit inside char and std::string so you don't have to do anything special there. If you need utf-8 string literals you must use the u8 prefix: u8"literal". Everything else should be standard file IO.
EDIT: Here are some links to the relevant documentation to help you get started:
ifstream (for reading from files)
ofstream (for writing to files)
unordered_map (for mapping 'keys' to 'values')
Outside of that it will probably just take a little Googling. File IO is very common so I'm sure you can find some good examples online. As long as your file format is consistent you shouldn't have too much trouble with the file parsing. Then the rest of it is just storing values in the map and then looking them up when you need them, which is pretty simple.

How to save a CSV file as UTF-8

I write the code to create the . CSV files out there with Thai characters. But when I open a file using Microsoft Excel Thai characters in that file a wrong.But when I open it in Notepad, and then I press Save. And open it in Excel again. It is desired I think it is because the program does not Encoding to utf-8.
I had to do to Program, save it as utf-8.
std:: ofstream MyCSVFile;
MyCSVFile.open("myfile.csv", std::ios::out | std::ios::app);
MyCSVFile << "Name,Address" << endl;
MyCSVFile <<name<<","<<address << endl;
MyCSVFile.close();
}
You need to write the BOM to the beginning of the file. Try this:
const char *bom = "\xef\xbb\xbf";
MyCSVFile << bom;
MyCSVFile << "Name...
This a good read: BOM in Wikipedia.
You need to do the following (assuming the file path is stored in FilePath):
Here is the code you should use:
const std::wstring fileStr(FilePath);
wofstream mFile(FilePath);
mFile.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
if (mFile.is_open())
{
const wchar_t *bom = L"\xef\xbb\xbf";
mFile << bom;
...
Now you can write the text, and of course close the file.

C++ edit a binary file with another

Solved! thanks all of you very much. My day has been made!(well morning, its 4am)
I'm trying to write a program in C++ that opens a .dat file in binary and replaces the first 1840 hex characters with that of another .dat file, while leaving the remaining hex values of the first .dat file the same. I have spent about 12 hours on this today and have had little success. I am a beginner programmer, I have taken one semester worth of c++ courses and we did not get to streams.
(it opens a file and everything, but deletes every thing after the new values have been added)
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
#include <cstring>
using namespace std;
int main (){
string filename;
long size;
char* memblock;
cout << " Enter a file to be modded by Mod.dat ";
cin >> filename;
ofstream infile ( filename ,std::ofstream::binary);
//filename: the file that will be opened and changed)
ifstream modFile ("Mod.dat", ifstream::binary);
// (mod.dat is the file that i get the first 1840 hex values from)
modFile.seekg (0,modFile.end);
size = modFile.tellg();
memblock = new char [size];
modFile.seekg (0, ios::beg);
modFile.read (memblock, size);
infile.write(memblock, 1840);
modFile.close();
infile.close();
cout << endl;
return 0;
}
Any help would be greatly appreciated, I hope there is some simple way to do this.
Solved! thanks all of you very much. My day has been made!(well morning, its 4am)
Edit:
You can modidy your file in place with something like :
std::fstream s(my_file_path, std::ios_base::binary);
s.seekp(position_of_data_to_overwrite, std::ios_base::beg);
s.write(my_data, size_of_data_to_overwrite);
std::fstream will not truncate your input file as std::ofstream does.
The other solution is to not use the same file for reading and writing. Use three files :
One for the output file.
One for the First input file.
One for the second input file.
fstream infile ( filename ,std::ofstream::binary); does not keeps the contents of the original file. Everything you write will erase the contents of the file.
Thus, you should:
open the output file
open the "Mod" file, read the first 1840 bytes from the first file, write them into the output file.
open the "main input file" file, move the cursor to 1840, read the remaining data and write it to the output file.
Depending on the "main input file" size, you may want to buffer you read/write operation.
My preferred fix, although Matthieu Rouget's fix does indeed work, is to just add ofstreeam::in to the opening of the input file:
ofstream infile ( filename.c_str(), std::ofstream::binary | ofstream::in);
(I had to use c_str() in my build, as glibc in my version doesn't take std::string as input).
I tested this on my local system (it took a while to realize that mod.dat is actually "Mod.dat"!)
It is probably a good idea to also check that the files actually opened, so something like this after ofstream infile line:
if (!infile)
{
cout << "Couldn't open " << filename << endl;
}
and similar for the modfile line.
And since you go through the effort of figuring out what the first part of the modfile size is, I would suggest that you also USE that for the writing of the file.

When saving to a file is there a way to not override whats already in the file?

When saving something to a text file is there a way to not override whats in the file already?
EX.
blah.txt
this is an example
fout << "of saving to a file.";
i want the "of saving to a file" to be added on to "this is an example" not to override it.
use the append flag, like this:
fstream fout("blah.txt", ios::app);
if you are opening it after declaration, use something like this:
fout.open("blash.txt", fstream::app);
You should open the file with the appropriate write mode in order to append to it instead of overwriting:
pFile = fopen ("myfile.txt","a");
(C style), or
fstream filestr ("myfile.txt", fstream::ate | fstream::out);
(C++ style). In the latter case, you may want to use fstream::app instead of fstream::ate - this sets the file pointer to the end of the file before each output operation.
Yes. You need to open the file in append mode.
ofstream fout("blah.txt", fstream::out | fstream::app);
You need to open the file output stream in append mode:
ofstream fout(<path>, ios::app);
You can manually set the write position if you want to
u need:
#include <stdio.h>
...
FILE *file = fopen("my_file.txt", "w");
fputs ("This is some text." , file);
fseek (file , 15, SEEK_SET);
fputs (" sam" ,file);
fclose (file);

How do you open a file in C++?

I want to open a file for reading, the C++ way. I need to be able to do it for:
text files, which would involve some sort of read line function.
binary files, which would provide a way to read raw data into a char* buffer.
You need to use an ifstream if you just want to read (use an ofstream to write, or an fstream for both).
To open a file in text mode, do the following:
ifstream in("filename.ext", ios_base::in); // the in flag is optional
To open a file in binary mode, you just need to add the "binary" flag.
ifstream in2("filename2.ext", ios_base::in | ios_base::binary );
Use the ifstream.read() function to read a block of characters (in binary or text mode). Use the getline() function (it's global) to read an entire line.
There are three ways to do this, depending on your needs. You could use the old-school C way and call fopen/fread/fclose, or you could use the C++ fstream facilities (ifstream/ofstream), or if you're using MFC, use the CFile class, which provides functions to accomplish actual file operations.
All of these are suitable for both text and binary, though none have a specific readline functionality. What you'd most likely do instead in that case is use the fstream classes (fstream.h) and use the stream operators (<< and >>) or the read function to read/write blocks of text:
int nsize = 10;
std::vector<char> somedata(nsize);
ifstream myfile;
myfile.open("<path to file>");
myfile.read(somedata.data(), nsize);
myfile.close();
Note that, if you're using Visual Studio 2005 or higher, traditional fstream may not be available (there's a new Microsoft implementation, which is slightly different, but accomplishes the same thing).
To open and read a text file line per line, you could use the following:
// define your file name
string file_name = "data.txt";
// attach an input stream to the wanted file
ifstream input_stream(file_name);
// check stream status
if (!input_stream) cerr << "Can't open input file!";
// file contents
vector<string> text;
// one line
string line;
// extract all the text from the input file
while (getline(input_stream, line)) {
// store each line in the vector
text.push_back(line);
}
To open and read a binary file you need to explicitly declare the reading format in your input stream to be binary, and read memory that has no explicit interpretation using stream member function read():
// define your file name
string file_name = "binary_data.bin";
// attach an input stream to the wanted file
ifstream input_stream(file_name, ios::binary);
// check stream status
if (!input_stream) cerr << "Can't open input file!";
// use function that explicitly specifies the amount of block memory read
int memory_size = 10;
// allocate 10 bytes of memory on heap
char* dynamic_buffer = new char[memory_size];
// read 10 bytes and store in dynamic_buffer
file_name.read(dynamic_buffer, memory_size);
When doing this you'll need to #include the header : <iostream>
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ofstream file;
file.open ("codebind.txt");
file << "Please writr this text to a file.\n this text is written using C++\n";
file.close();
return 0;
}
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
ifstream in_stream; // fstream command to initiate "in_stream" as a command.
char filename[31]; // variable for "filename".
cout << "Enter file name to open :: "; // asks user for input for "filename".
cin.getline(filename, 30); // this gets the line from input for "filename".
in_stream.open(filename); // this in_stream (fstream) the "filename" to open.
if (in_stream.fail())
{
cout << "Could not open file to read.""\n"; // if the open file fails.
return;
}
//.....the rest of the text goes beneath......
}
Follow the steps,
Include Header files or name space to access File class.
Make File class object Depending on your IDE platform ( i.e,
CFile,QFile,fstream).
Now you can easily find that class methods to open/read/close/getline or else of any file.
CFile/QFile/ifstream m_file;
m_file.Open(path,Other parameter/mood to open file);
For reading file you have to make buffer or string to save data and you can pass that variable in read() method.
**#include<fstream> //to use file
#include<string> //to use getline
using namespace std;
int main(){
ifstream file;
string str;
file.open("path the file" , ios::binary | ios::in);
while(true){
getline(file , str);
if(file.fail())
break;
cout<<str;
}
}**
#include <fstream>
ifstream infile;
infile.open(**file path**);
while(!infile.eof())
{
getline(infile,data);
}
infile.close();
fstream are great but I will go a little deeper and tell you about RAII.
The problem with a classic example is that you are forced to close the file by yourself, meaning that you will have to bend your architecture to this need. RAII makes use of the automatic destructor call in C++ to close the file for you.
Update: seems that std::fstream already implements RAII so the code below is useless. I'll keep it here for posterity and as an example of RAII.
class FileOpener
{
public:
FileOpener(std::fstream& file, const char* fileName): m_file(file)
{
m_file.open(fileName);
}
~FileOpeneer()
{
file.close();
}
private:
std::fstream& m_file;
};
You can now use this class in your code like this:
int nsize = 10;
char *somedata;
ifstream myfile;
FileOpener opener(myfile, "<path to file>");
myfile.read(somedata,nsize);
// myfile is closed automatically when opener destructor is called
Learning how RAII works can save you some headaches and some major memory management bugs.