C++: How to correctly write in a .csv file - c++

I have following data in a text file
04EC3AC705EA3AC8042C3BC7051A3AC8043C3AD7054A3AE8
I want to put this data into a .csv file in a single column as follows.
04EC,3AC7
05EA,3AC8
042C,3BC7
051A,3AC8
043C,3AD7
054A,3AE8
What I tried so far is:
fp=fopen("D:/pattern.csv", "a+")
Then I read the original values from the text file in a buffer
fwrite(buffer, 48,1,fp);
But again I get all values in a single cell in the csv sheet.
Please tell me a better way to achieve this. I developed this code in MSVS 2010 win32 and I will be using this code in another application written in C++/CLI Windows form application.
Thanks

If I well understand, your input file contains only one line with a single string. And you want to convert it to pairs of 4 char ?
What about a more 'C++' way like this ?
std::string input_file_name = "input.txt";
std::string output_file_name = "output.csv";
std::string line;
std::ifstream input_file(input_file_name.c_str());
input_file >> line;
std::ofstream output_file(output_file_name.c_str());
for(unsigned long int i = 0; i + 7 < line.length(); i += 8)
output_file << line.substr(i, 4) << "," << line.substr(i + 4, 4) << std::endl;

Related

Picking a random line from a text file

I need to write an 8 ball code that has eleven options to display and it needs to pull from a text file. I have it taking lines from the text file but sometimes it takes an empty line with no writing. And I need it to only take a line that has writing.
Here are that options it needs to draw from:
Yes, of course!
Without a doubt, yes.
You can count on it.
For sure!Ask me later.
I'm not sure.
I can't tell you right now.
I'll tell you after my nap.
No way!I don't think so.
Without a doubt, no.
The answer is clearly NO.
string line;
int random = 0;
int numOfLines = 0;
ifstream File("file.txt");
srand(time(0));
random = rand() % 50;
while (getline(File, line))
{
++numOfLines;
if (numOfLines == random)
{
cout << line;
}
}
}
IMHO, you need to either make the text lines all the same length, or use a database (table) of file positions.
Using File Positions
Minimally, create a std::vector<pos_type>.
Next read the lines from the file, recording the file position of the beginning of the string:
std::vector<std::pos_type> text_line_positions;
std::string text;
std::pos_type file_position = 0;
while (std::getline(text_file, text)
{
text_line_positions.push_back(file_position);
// Read the start position of the next line.
file_position = text_file.tellg();
}
To read a line from a file, get the file position from the database, then seek to it.
std::string text_line;
std::pos_type file_position = text_line_positions[5];
text_file.seekg(file_position);
std::getline(text_file, text_line);
The expression, text_line_positions.size() will return the number of text lines in the file.
If File Fits In Memory
If the file fits in memory, you could use std::vector<string>:
std::string text_line;
std::vector<string> database;
while (getline(text_file, text_line))
{
database.push_back(text_line);
}
To print the 10 line from the file:
std::cout << "Line 10 from file: " << database[9] << std::endl;
The above techniques minimize the amount of reading from the file.

cannot read character value '26' from file(substitute character) in c++

hi,
I've just done something like below in c++: - ON - WINDOWS 10
//1. Serialize a number into string then write it to file
std::string filename = "D:\\Hello.txt";
size_t OriNumber = 26;
std::string str;
str.resize(sizeof(size_t));
memcpy(&str[0], reinterpret_cast<const char*>(&OriNumber), str.size());
std::ofstream ofs(filename);
ofs << str << std::endl;
ofs.close();
//2. Now read back the string from file and deserialize it
std::ifstream ifs(filename);
std::string str1{std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>()};
// 3. Expect that the string str1 will not be empty here.
size_t DeserializedNumber = *(reinterpret_cast<const size_t*>(str1.c_str()));
std::cout << DeserializedNumber << std::endl;
At step 3, I could not read the string from file, even if I opened the file with notepad++, it showed several characters. At last line we still have the value of DeserializedNumber got printed, but it is due to str1.c_str() is now a valid pointer with some garbage value.
After debugged the program, I found that std:ifstream will get the value -1(EOF) at beginning of the file, and as explanation of wikipedia, 26 is value of Substitue Character and sometime is considered as EOF.
My question is:
if I can't read value 26 from file as above, then how can serialization library serialize this value to bytes?
and Do we have some way to read/write/transfer this value properly if still serialize the value 26 as my way above?
thanks,

Edit file line by line number - C++

I'm trying to edit a .dat file. I want to read a line by line number, turn the content to int, edit and replace it.
like I want to edit line number 23, it says "45" I need to make it "46". How do I do that?
ofstream f2;
theBook b;
f2.open("/Users/vahidgr/Documents/Files/UUT/ComputerProjects/LibraryCpp/LibraryFiles/Books.dat", ios::app);
ifstream file("/Users/vahidgr/Documents/Files/UUT/ComputerProjects/LibraryCpp/LibraryFiles/Books.dat");
cout<<"In this section you can add books."<<endl;
cout<<"Enter ID: "; cin>>b.id;
cout<<"Enter Name: "; cin>>b.name;
string sID = to_string(b.id);
string bookName = b.name;
string line;
int lineNumber = 0;
while(getline(file, line)) {
++lineNumber ;
if(line.find(bookName) != string::npos && line.find(sID) != string::npos) {
int countLineNumber = lineNumber + 4;
registered = true;
f2.close();
break;
}
}
Inside the file:
10000, book {
author
1990
20
20
}
If your file is small (such as under 1GB), you can just read the entire file into memory line-by-line as a std::vector<std::string> (Hint: use std::getline). Then, edit the required line, and overwrite the file with an updated one.
Iterate Byte for Byte through the file and count line breaks (\n or \r\n on Windows).
After 22 breaks, insert bytes that say “46”. It should overwrite the existing bytes.
If your modifications are the exact size of the original text, you can write back to the same file. Otherwise, you will need to write your modifications to a new file.
Since your file is variable length text, separated by newlines, we'll have to skip lines until we get to the desired line:
const unsigned int desired_line = 23;
std::ifstream original_file(/*...*/);
std::ofstream modified_file(/*...*/);
// Skip lines
std::string text_line;
for (unsigned int i = 0; i < desired_line - 1; ++i)
{
std::getline(original_file, text_line);
modified_file << text_line << std::endl;
}
// Next, read the text, modify and write to the original file
//... (left as an exercise for the OP, since this was not explicit in the post.
// Write remaining text lines to modified file
while (std::getline(original_file, text_line))
{
modified_file << text_line << std::endl;
}
Remember to write your modified text to the modified file before copying the remaining text.
Edit 1: By record / object
This looks like an X-Y problem.
A preferred method is to read in the objects, modify the object, then write the objects to a new file.

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.

Woking With BMP File in C++, Ubuntu

I am trying to work with a bmp file in linux with g++ compiler. I am using C++ language.
I Need to load a .bmp file from the standard input. for example:
./a.out < test.bmp
So I need a Code to do this job. I think storing the whole .bmp file is good by I don't know how to do this.
I Tried this code but it didn't Work:
vector<int> bitmap;
int b;
while ( cin >> b ) {
bitmap.push_back(b);
cout << "!" << endl;
}
So How should I Do this?
cin >> b reads file in text mode, this is not for binary files. use something like this:
ifstream myFile ("test.bmp", ios::in | ios::binary);
to open stream for file, and then
if (!myFile.read (buffer, 100)) {
// do thomething with data in buffer
}
I Found an answer That Works Correctly.
This Code Reads The bmp_info_header from the *.bmp file from the standard input:
char bmpHeader[54];
cin.get(bmpHeader, 54);
the "54" in cin.get() tells the system to accept the max 54 numbers from the input and ignores the other.
now for example if we want to find the *.bmp size we should use this code:
int filesize = *((int*)(headers + 2));