This is a program to convert a text file to a C string.
It is offered as a service to the comp.lang.c community.
Originally I thought it would be a five minute job to program. In fact there
are subtle problems, such as the fact that a text file may wrap lines.
It will be appearing on my website as soon as I get update access, assuming
no one finds anything wrong with it.
/*
texttostring - converts a text file to a C string
By Malcolm McLean
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "texttostring.h"
char *fnametoid(char *path);
char *loadfile(FILE *fp);
/*
print out a message showing how to use the program
*/
int usage(void)
{
printf("Program to take in a text file and spit it out as a C string\n");
printf("Usage: texttostring <infile.txt[id]\n");
printf(" infile.txt - text file\n");
printf(" id - identifier of string, default is file name\n");
exit(EXIT_FAILURE);
}
/*
main function
argv[1] - the name of the file to turn into a C string
argv[2] - (optional) name of the identifier to use
*/
int main(int argc, char **argv)
{
FILE *fp;
char *id;
char *str;
char *cstr;
long i;
if(argc != 2 && argc != 3)
usage();
if(argc == 3)
id = argv[2];
else
id = fnametoid(argv[1]);
if(!id)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
fp = fopen(argv[1], "r");
if(!fp)
{
fprintf(stderr, "Couldn't open file\n");
exit(EXIT_FAILURE);
}
str = loadfile(fp);
fclose(fp);
if(str)
{
cstr = texttostring(str);
if(!cstr)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
printf("char *%s = ", id);
for(i=0;cstr[i];i++)
fputc(cstr[i], stdout);
printf(";\n");
}
else
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
if(id != argv[2])
free(id);
free(str);
free(cstr);
return 0;
}
/*
convert a file name to a valid C identifier, by replacing
non-alphanmerics with dights.
*/
char *fnametoid(char *path)
{
char *answer;
char *ptr;
answer = malloc(strlen(path) + 2);
if(!answer)
return 0;
ptr = answer;
if(!isalpha(*path))
*ptr++ = 'a';
while(*path)
{
if(isalnum(*path))
*ptr++ = *path;
else
*ptr++ = '_';
path++;
}
*ptr = 0;
return answer;
}
/*
load a text file into memory
*/
char *loadfile(FILE *fp)
{
long len;
long i = 0;
char *answer;
char *temp;
int ch;
fseek(fp, 0, SEEK_END);
len = ftell(fp);
fseek(fp, 0, SEEK_SET);
answer = malloc(len + 100 + len/10);
if(!answer)
return 0;
len = len + 100 + len/10;
while( (ch = fgetc(fp)) != EOF)
{
answer[i++] = (char) ch;
if(i < 0)
{
free(answer);
return 0;
}
if(i >= len - 1)
{
temp = realloc(answer, len + 100 + len/10);
if(!temp)
{
free(answer);
return 0;
}
answer = temp;
len = len + 100 + len/10;
}
}
answer[i] = 0;
return answer;
}
/* header file */
#ifndef texttostring_h
#define texttostring_h
char *texttostring(const char *str);
int escaped(int ch);
char escapechar(int ch);
#endif
/*
text to string functions
*/
#include <string.h>
#include <stdlib.h>
#include "texttostring.h"
static size_t linesbiggerthan(const char *str, size_t maxlen);
/*
convert a string to a C language string;
Params:
str - the string to convert
Returns: C version of string, 0 on out of memory
Notes: newlines are represented by breaks in the string.
*/
char *texttostring(const char *str)
{
size_t len = 0;
size_t i;
size_t j = 0;
size_t linelen = 0;
char *answer;
for(i=0;str[i];i++)
{
if(str[i] == '\n')
len += 5;
else if(escaped(str[i]))
len+=2;
else
len += 1;
}
len += linesbiggerthan(str, 100) * 3;
len++;
len += 2;
answer = malloc(len);
if(!answer)
return 0;
answer[j++] = '"';
for(i=0;str[i];i++)
{
if(str[i] == '\n' && str[i+1] != 0)
{
answer[j++] = '\\';
answer[j++] = 'n';
answer[j++] = '\"';
answer[j++] = '\n';
answer[j++] = '\"';
linelen = 0;
}
else if(escaped(str[i]))
{
answer[j++] = '\\';
answer[j++] = escapechar(str[i]);
linelen++;
}
else
{
answer[j++] = str[i];
linelen++;
}
if(linelen == 100 && str[i+1] != '\n')
{
answer[j++] = '\"';
answer[j++] = '\n';
answer[j++] = '\"';
linelen = 0;
}
}
answer[j++] = '\"';
answer[j++] = 0;
return answer;
}
/*
test if a character is escaped in C
Params: ch - the character to test
Returns: 1 if escaped in C strings, else 0
*/
int escaped(int ch)
{
char *escapes = "\a\b\f\n\r\t\v\?\'\"\\";
if(ch == 0)
return 1;
return strchr(escapes, ch) ? 1 : 0;
}
/*
get the escape character to represent ch
Params: ch - an escaped character
Returns: character that stands in for it in esacpe sequence,
0 if ch is not an escaped character
*/
char escapechar(int ch)
{
char *escapes = "\a\b\f\n\r\t\v\?\'\"\\";
char *characters = "abfnrtv?\'\"\\";
char *ptr;
if(ch == 0)
return '0';
ptr = strchr(escapes, ch);
if(ptr)
return characters[ptr - escapes];
else
return 0;
}
/*
get the number of lines bigger than a certain value
*/
static size_t linesbiggerthan(const char *str, size_t maxlen)
{
size_t len = 0;
size_t answer = 0;
while(*str)
{
if(*str == '\n')
len = 0;
else
{
len++;
if(len maxlen)
{
len = 0;
answer++;
}
}
str++;
}
return answer;
}
--
www.personal.leeds.ac.uk/~bgy1mm
freeware games to download.