J
jacob navia
Why are C interfaces so low level?
We discussed a bit about this in the thread about getting an URL from
the internet.
Take, for instance, we all some day needed to read an entire
file into RAM to process it. Why there isn't
char *strfromfile(const char *file_name,const char *mode);
As a holidays present, here it is.
#include <string.h>
#include >errno.h>
#include <stdio.h>
#include <stdlib.h>
char *strfromfile(const char *fname,const char *mode)
{
if (fname == NULL || mode == NULL) {
errno = EINVAL;
return NULL;
}
FILE *f = fopen(fname,"rb");
if (f == NULL) {
errno = ENOENT;
return NULL;
}
if (fseek(f,0,SEEK_END) != 0) {
ioerror:
errno = EIO; // IO error
fclose(f);
return NULL;
}
long l = ftell(f);
if (l < 0) goto ioerror;
if (fseek(f,0,SEEK_SET) != 0)
goto ioerror;
char *result = malloc(l+1);
if (result == NULL) {
errno = ENOMEM;
fclose(f);
return NULL;
}
if (fread(result,1,l,f) <= 0)
goto ioerror;
result[l] = 0;
fclose(f);
if (strchr(mode,'b') == NULL) {
char *src = result,*dst = result;
while ((src - result) < l) {
if (*src != '\r')
*dst++ = *src;
src++;
}
*dst = 0;
}
return result;
}
Argument "mode" should be either "r" or "rb" for binary or text mode.
This can be omitted in Unix systems, where this stupid distinction
doesn't exist.
If I do not find a "b" in the "mode" string I eliminate CRs from the
string.
NOTE: This function will not run in the DS9000
We discussed a bit about this in the thread about getting an URL from
the internet.
Take, for instance, we all some day needed to read an entire
file into RAM to process it. Why there isn't
char *strfromfile(const char *file_name,const char *mode);
As a holidays present, here it is.
#include <string.h>
#include >errno.h>
#include <stdio.h>
#include <stdlib.h>
char *strfromfile(const char *fname,const char *mode)
{
if (fname == NULL || mode == NULL) {
errno = EINVAL;
return NULL;
}
FILE *f = fopen(fname,"rb");
if (f == NULL) {
errno = ENOENT;
return NULL;
}
if (fseek(f,0,SEEK_END) != 0) {
ioerror:
errno = EIO; // IO error
fclose(f);
return NULL;
}
long l = ftell(f);
if (l < 0) goto ioerror;
if (fseek(f,0,SEEK_SET) != 0)
goto ioerror;
char *result = malloc(l+1);
if (result == NULL) {
errno = ENOMEM;
fclose(f);
return NULL;
}
if (fread(result,1,l,f) <= 0)
goto ioerror;
result[l] = 0;
fclose(f);
if (strchr(mode,'b') == NULL) {
char *src = result,*dst = result;
while ((src - result) < l) {
if (*src != '\r')
*dst++ = *src;
src++;
}
*dst = 0;
}
return result;
}
Argument "mode" should be either "r" or "rb" for binary or text mode.
This can be omitted in Unix systems, where this stupid distinction
doesn't exist.
If I do not find a "b" in the "mode" string I eliminate CRs from the
string.
NOTE: This function will not run in the DS9000