K
Kinbote
Hi,
I'm trying to make a function that opens a file, reads it in line by
line, puts each line into an malloc'd array, and returns the array. I
suspect I'm going about it in an atypical fashion, as I'm avoiding the
use of fscanf and fgets to read in lines. I don't want to have to
specify a temporary char* buffer to read in each line, and then have
to concern myself with the (remote) possibility of overflows or with
increasing the buffer size via malloc at runtime if necessary. So I'm
using stat to get the size of the file, malloc'ing that size +1, then
copying each character from the file to that malloc'd block, inserting
nulls for newlines. (I don't mind whether fgetc is possibly slower
than using another I/O function.) Basically I'm turning a block of
memory into a 2d array, but I'm getting this error:
gcc -O3 -Wall -std=c99 -pedantic -o Slurp Slurp.c
Slurp.c:173: warning: passing argument 2 of 'memcpy' makes pointer
from integer without a cast
I'm using gcc 4.0.1 on OSX 10.4.8.
Is there perhaps a better, more canonical way of doing this very
common chore? I looked through the relevant sections of the C-faq in
and around 7.4, but I wanted to check if this way of doing it is also
going to work, or if there is another similar solution.
Best,
Rod
typedef struct {
size_t length;
char** data;
} DynStrArray;
DynStrArray* slurp(char *file_nm) {
char file_err[256];
DynStrArray *lines = malloc(sizeof *lines);
if (!lines) fatal("slurp: DynStrArray malloc", NULL);
int c, i;
FILE *fh;
struct stat file_info;
if (stat(file_nm, &file_info) == -1) fatal("stat: %s", file_nm);
#if DEBUG
printf("%s stat size: %d\n", file_nm, (int)file_info.st_size);
#endif
fh = fopen(file_nm, "r");
if (fh == NULL) fatal("%s: fopen error on file %s: %d", file_err,
file_nm, ferror(fh));
lines->data = malloc(file_info.st_size + 1);
lines->length = 0;
if (lines->data == NULL) fatal("slurp: malloc ", NULL);
i = 0;
while ((c = fgetc(fh)) != EOF) {
if (c == '\n') {
lines->data[i++] = '\0';
lines->length++;
}else{
lines->data[i++] = c;
/* tried this too, give same error:
memcpy(lines->data[i++], c, sizeof c); */
}
}
fclose(fh);
#if DEBUG
printf("slurp: lines length: %d\n", (int)sizeof(lines->data));
printf("slurped: %s\n", *(lines->data));
#endif
return lines;
}
I'm trying to make a function that opens a file, reads it in line by
line, puts each line into an malloc'd array, and returns the array. I
suspect I'm going about it in an atypical fashion, as I'm avoiding the
use of fscanf and fgets to read in lines. I don't want to have to
specify a temporary char* buffer to read in each line, and then have
to concern myself with the (remote) possibility of overflows or with
increasing the buffer size via malloc at runtime if necessary. So I'm
using stat to get the size of the file, malloc'ing that size +1, then
copying each character from the file to that malloc'd block, inserting
nulls for newlines. (I don't mind whether fgetc is possibly slower
than using another I/O function.) Basically I'm turning a block of
memory into a 2d array, but I'm getting this error:
gcc -O3 -Wall -std=c99 -pedantic -o Slurp Slurp.c
Slurp.c:173: warning: passing argument 2 of 'memcpy' makes pointer
from integer without a cast
I'm using gcc 4.0.1 on OSX 10.4.8.
Is there perhaps a better, more canonical way of doing this very
common chore? I looked through the relevant sections of the C-faq in
and around 7.4, but I wanted to check if this way of doing it is also
going to work, or if there is another similar solution.
Best,
Rod
typedef struct {
size_t length;
char** data;
} DynStrArray;
DynStrArray* slurp(char *file_nm) {
char file_err[256];
DynStrArray *lines = malloc(sizeof *lines);
if (!lines) fatal("slurp: DynStrArray malloc", NULL);
int c, i;
FILE *fh;
struct stat file_info;
if (stat(file_nm, &file_info) == -1) fatal("stat: %s", file_nm);
#if DEBUG
printf("%s stat size: %d\n", file_nm, (int)file_info.st_size);
#endif
fh = fopen(file_nm, "r");
if (fh == NULL) fatal("%s: fopen error on file %s: %d", file_err,
file_nm, ferror(fh));
lines->data = malloc(file_info.st_size + 1);
lines->length = 0;
if (lines->data == NULL) fatal("slurp: malloc ", NULL);
i = 0;
while ((c = fgetc(fh)) != EOF) {
if (c == '\n') {
lines->data[i++] = '\0';
lines->length++;
}else{
lines->data[i++] = c;
/* tried this too, give same error:
memcpy(lines->data[i++], c, sizeof c); */
}
}
fclose(fh);
#if DEBUG
printf("slurp: lines length: %d\n", (int)sizeof(lines->data));
printf("slurped: %s\n", *(lines->data));
#endif
return lines;
}