Reputation: 1415
I have a data file data.txt which includes character and numeric data.
Usually I read the data.txt in my program by using file streams like
ifstream infile("C:\\data.txt",ios::in);
then use infile.getline
to read the values.
Is it anyway possible to have the data.txt file included to the project and compile
it with the project such that when I read the file I do not have to worry about the path
of the file ( I mean I just use something like ifstream infile("data.txt",ios::in) )
.
Moreover if I can compile the file with my project I will not have to worry about providing a separate data.txt file with my release build to anyone else who wants to use my program.
I do not want to change the data.txt file to some kind of header file. I want to keep the
.txt file as is and somehow package it within my executable that I am building. I still
want to keep using ifstream infile("data.txt",ios::in)
and read the lines from the file
but want data.txt file to be with the project just like anyother .h or .cpp files.
I am using C++ visual studio 2010. It would be kind of someone to provide some insight into the above thing I am trying to do.
I managed to use the code below to read in the data file as resource
HRSRC hRes = FindResource(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_TEXT1), _T("TEXT"));
DWORD dwSize = SizeofResource(GetModuleHandle(NULL), hRes); HGLOBAL hGlob = LoadResource(GetModuleHandle(NULL), hRes);
const BYTE* pData = reinterpret_cast<const BYTE*>(::LockResource(hGlob));
but how do I read the separate lines ? Somehow I am unable to read the separate lines. I can't seem to differentiate one line from another.
Upvotes: 4
Views: 3661
Reputation: 1
The above python works, but this variation is faster (by a factor of about 1000 on a 1MB file - as it avoids the quadratic string build):
#!/usr/bin/python3
import sys
f = open(sys.argv[1],"rb") # Open the file in read binary mode
s = "unsigned char text_txt_data[] = {\n"
b = f.read()
db = bytes(b)
l = 0
fw = open(sys.argv[2],"w")
fw.write(s);
for i in range(0, len(db)):
if l >= 16:
l = 0
#s = s + "\n"
fw.write(f"\n{hex(db[i])},")
else:
fw.write(f"{hex(db[i])},")
l = l + 1
fw.write("\n}\n\n")
print(f"read {f.tell()} bytes from {sys.argv[1]}: writing {fw.tell()} bytes to {sys.argv[2]}...")
f.close() # Close the file
# Write the resultant code to a file that can be compiled
fw.close()
Upvotes: -1
Reputation: 1421
For any kind of file, base on RBerteig anwser you could do something simple as this with python:
This program will generate a text.txt.c file that can be compiled and linked to your code, to embed any text or binary file directly to your exe and read it directly from a variable:
import struct; # Needed to convert string to byte
f = open("text.txt","rb") # Open the file in read binary mode
s = "unsigned char text_txt_data[] = {"
b = f.read(1) # Read one byte from the stream
db = struct.unpack("b",b)[0] # Transform it to byte
h = hex(db) # Generate hexadecimal string
s = s + h; # Add it to the final code
b = f.read(1) # Read one byte from the stream
while b != "":
s = s + "," # Add a coma to separate the array
db = struct.unpack("b",b)[0] # Transform it to byte
h = hex(db) # Generate hexadecimal string
s = s + h; # Add it to the final code
b = f.read(1) # Read one byte from the stream
s = s + "};" # Close the bracktes
f.close() # Close the file
# Write the resultan code to a file that can be compiled
fw = open("text.txt.c","w");
fw.write(s);
fw.close();
Will generate something like
unsigned char text_txt_data[] = {0x52,0x61,0x6e,0x64,0x6f,0x6d,0x20,0x6e,0x75...
You can latter use your data in another c file using the variable with a code like this:
extern unsigned char text_txt_data[];
Right now I cant think of two ways to converting it to readable text. Using memory streams or converting it to a c-string.
Upvotes: -1
Reputation: 683
You can put the contents of the file in std::string variable:
std::string data_txt = "";
Then use sscanf or stringstream from STL to parse the contents.
One more thing - you will need to handle special characters like '"' by using \ character before each one.
Upvotes: 0
Reputation: 2395
There was a similar question, that also required inclusion of external file into C++ code. Please check my answer here. Another way is to include a custom resource in your project, and then use FindResource, LoadResource, LockResource to access it.
Upvotes: 0
Reputation: 101
I can just give you a workaround, if you don't want to worry about the path of the file, you can just: - add you file to your project - add a post building event to copy your data.txt file in your build folder.
Upvotes: 0