Skip to content

Instantly share code, notes, and snippets.

@armornick
Created March 6, 2018 08:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save armornick/9e71c9c5f6990074d945cccccb4c01f3 to your computer and use it in GitHub Desktop.
Save armornick/9e71c9c5f6990074d945cccccb4c01f3 to your computer and use it in GitHub Desktop.
Embed text file as C string
#include <cstdio>
#include <cctype>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <stdexcept>
#define FILE_LIST_FN "file_list.txt"
#define OUTPUT_LINE_SIZE 128
typedef std::vector<std::string> strvector;
std::string make_output_name(const std::string& fileName)
{
std::string result = fileName;
std::replace(result.begin(), result.end(), '.', '_');
return result;
}
std::string load_file(const char *fileName)
{
FILE *inputf = std::fopen(fileName, "rb");
if (inputf == NULL)
{
throw std::runtime_error("could not open input file");
}
std::fseek(inputf, 0, SEEK_END);
long fsize = std::ftell(inputf);
std::rewind(inputf);
std::vector<char> buff (fsize);
std::fread(&buff[0], sizeof(buff[0]), buff.size(), inputf);
return std::string(buff.begin(), buff.end());
}
void load_file_names(const char *fileName, strvector& nameList)
{
std::stringstream buff;
std::string raw = load_file(fileName);
for (int i = 0; i < raw.size(); i++)
{
char c = raw[i];
// on line-end, add string to output list
if (c == '\n')
{
nameList.push_back( buff.str() );
// clear string buffer
buff.str( std::string() );
buff.clear();
continue;
}
// skip spaces
if (std::isspace(c)) continue;
// add character to buffer if non-space
buff << c;
}
// check to see if there was something on the last line
if (!buff.str().empty())
{
nameList.push_back( buff.str() );
}
}
void embed_file(const std::string& fileName, std::stringstream& output)
{
int count = 0;
std::string contents = load_file(fileName.c_str());
output << "const char " << make_output_name(fileName) << "[] = \n\t\"";
for (int i = 0; i < contents.size(); i++)
{
char c = contents[i];
switch (c)
{
case '\\':
{
output << "\\\\";
count += 2;
continue;
}
case '\"':
{
output << "\\\"";
count += 2;
continue;
}
case '\n':
{
output << "\\n";
count += 2;
continue;
}
case '\t':
{
output << "\\t";
count += 2;
continue;
}
case '\r': continue; // skip carriage return
default:
{
output << c;
count++;
}
}
if (count >= OUTPUT_LINE_SIZE)
{
output << "\"\n\t\"";
count = 0;
}
}
output << "\";\n\n";
}
int main(int argc, char const *argv[])
{
strvector nameList;
load_file_names(FILE_LIST_FN, nameList);
std::stringstream output;
for (strvector::iterator& it = nameList.begin(); it != nameList.end(); it++)
{
embed_file(*it, output);
}
std::printf("%s", output.str().c_str());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment