user1612986
user1612986

Reputation: 1415

Including data file into C++ project

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.

Update

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

Answers (5)

Jameson
Jameson

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

felknight
felknight

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

vmax33
vmax33

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

DNT
DNT

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

Refresh It Solutions
Refresh It Solutions

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

Related Questions