473,387 Members | 1,516 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

read a file's line into an array, error: makes pointer from integer without a cast

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;
}

Apr 5 '07 #1
6 3529
Kinbote wrote:

<stuff>
>
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
>
typedef struct {
size_t length;
char** data;
Note the type of data, a pointer to char*
int c, i;
Note the type of i, int.
lines->data[i++] = c;
Here you attempt to assign and int to a char*.

--
Ian Collins.
Apr 5 '07 #2
Kinbote wrote:
>
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
....

Very simple. Get ggets.zip and modify it to return on encountering
EOF rather than '\n'.
Done. See:

<http://cbfalconer.home.att.net/download/

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews

--
Posted via a free Usenet account from http://www.teranews.com

Apr 7 '07 #3
On Apr 5, 8:20 am, "Kinbote" <rodk...@gmail.comwrote:
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.
That's a bit much for one function. You might consider
having the function take an open FILE * as an argument.
You also might consider having another function determine
the size and allocate the array (and perhaps also allocating
space for each member of the array, confusion about which
seems to be the root cause of your problem below.)

<snip>
typedef struct {
size_t length;
char** data;
} DynStrArray;
So, data is to be the array of pointers to the lines...
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);
Note that stat is not standard C.
>
fh = fopen(file_nm, "r");
if (fh == NULL) fatal("%s: fopen error on file %s: %d", file_err,
file_nm, ferror(fh));
You should get a compiler warning here about the possible
use of uninitialized variable file_err. (Unless I'm being
blind, I don't see you set it anywhere.)
>
lines->data = malloc(file_info.st_size + 1);
Hmmm. That's odd. Your declarations indicate that
lines->data is to be an array of pointers, so it should have
as many elements as the file as lines. But this
allocation looks like you intend for lines->data
to be a data buffer holding the entire file. Perhaps
you are just overallocating so that you know you'll
have enough elements, but I suspect not.
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); */
Right. You are definitely dumping the contents of
the file into lines->data. So where is the
array of pointers? lines->length will give you
the line count of the file, but you need an array
of that many pointers to return.
What you could do is add a 3rd member to the
structure, of type char *, and call it buf.
Replace all instances of data above with buf.
Rename data ptr_array. After you've counted
the lines, allocate space for ptr_array, and
go back through buf, assigning each member
of ptr_array the address of the start of the line.

eg, your code doesn't match your documentation. You
said you would return an array of pointers, but
what you're really doing is returning a large
buffer with lots of contiguous strings.

Apr 7 '07 #4
Bill Pursell said:
On Apr 5, 8:20 am, "Kinbote" <rodk...@gmail.comwrote:
>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.

That's a bit much for one function.
It's a single well-defined task:

int LoadTextFile(textfile *tf, const char *filename);

You could decompose it internally, of course - and indeed you should -
but I don't think the task is too big for one function to manage.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 7 '07 #5
Richard Heathfield <rj*@see.sig.invalidwrites:
Bill Pursell said:
>On Apr 5, 8:20 am, "Kinbote" <rodk...@gmail.comwrote:
>>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.

That's a bit much for one function.

It's a single well-defined task:

int LoadTextFile(textfile *tf, const char *filename);

You could decompose it internally, of course - and indeed you should -
but I don't think the task is too big for one function to manage.
Agreed, but -- what is this type "textfile", and where are the
contents of the file stored?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 7 '07 #6
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>Bill Pursell said:
>>On Apr 5, 8:20 am, "Kinbote" <rodk...@gmail.comwrote:
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.

That's a bit much for one function.

It's a single well-defined task:

int LoadTextFile(textfile *tf, const char *filename);

You could decompose it internally, of course - and indeed you should
- but I don't think the task is too big for one function to manage.

Agreed, but -- what is this type "textfile",
That's a design issue, but I had in mind something like:

struct textfile_
{
char **line;
size_t maxlines;
size_t currlines;
};

typedef struct textfile_ textfile;

The OP may well wish to store other kinds of information in there - e.g.
the original filename, that sort of thing.
and where are the
contents of the file stored?
Again, that's a design issue.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 7 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Simon Schaap | last post by:
Hello, I have encountered a strange problem and I hope you can help me to understand it. What I want to do is to pass an array of chars to a function that will split it up (on every location where...
20
by: fix | last post by:
Hi all, I feel unclear about what my code is doing, although it works but I am not sure if there is any possible bug, please help me to verify it. This is a trie node (just similar to tree nodes)...
19
by: ranjeet | last post by:
Hay Guys can you all suggest me the points on the below issue Problem : The thing is that I have the data some thing like this. 1486, 2168, 3751, 9074, 12134, 13944, 17983, 19173, 21190,...
4
by: Dawn Minnis | last post by:
Hi When I compile my files I get the following: driver.c: In function `main': driver.c:49: warning: assignment makes integer from pointer without a cast driver.c:50: warning: assignment...
11
by: truckaxle | last post by:
I am trying to pass a slice from a larger 2-dimensional array to a function that will work on a smaller region of the array space. The code below is a distillation of what I am trying to...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
15
by: Paminu | last post by:
Still having a few problems with malloc and pointers. I have made a struct. Now I would like to make a pointer an array with 4 pointers to this struct. #include <stdlib.h> #include <stdio.h>...
7
by: Yuri_Юрий | last post by:
I'm confused about the VARIABLE LENGTH ARRAYS. {scanf("%d",&n);float a;} In which compiler can I use it? I tried VC++6.0 SP6,but it's reported error:CONSTANT EXPRESSION! Another question, What...
8
by: Frank Liebelt | last post by:
Hi I try to convert a int array into a char array. My code: void exec() { char mds; int i; int mdc =...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.