473,399 Members | 3,832 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,399 software developers and data experts.

read line function outputs weird results

the following code is supposed to read a whole line upto a new line
char from a file. however it does not work. it is producing weird
results. please help. I had error checking in there for mallocs and
ect, but i removed them to help me debug. thanks.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void freadl ( FILE *stream, char **string ) {

char next = fgetc ( stream );
char *line;

line = (char*) malloc (1*sizeof(char));

while ( next != '\n' ) {

line = (char*) realloc ( line, (strlen(line) + 1) * sizeof(char) );
line [strlen(line)] = next;
next = fgetc (stream );
}

*string = (char*) malloc((strlen(line))*sizeof(char));
strcpy (*string,line);
free(line);

}

int main ( int argc, char *argv[] ) {

FILE *fp;
fp = fopen ( "fread.c", "r" );

char *str;
freadl ( fp , &str );

printf ( "str = %s, with size of %d\n", str, strlen (str) );

int i;

for ( i = 0; i < strlen (str); i++ ){

char now = str[i];
printf ( "chr = %c, # = %d\n", now,now);

}

}

Feb 14 '07 #1
14 2695
WStoreyII wrote:
the following code is supposed to read a whole line upto a new line
char from a file. however it does not work. it is producing weird
results. please help. I had error checking in there for mallocs and
ect, but i removed them to help me debug. thanks.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void freadl ( FILE *stream, char **string ) {

char next = fgetc ( stream );
char *line;

line = (char*) malloc (1*sizeof(char));
Why oh why are people still adding these extraneous casts? Not only
that, but sizeof(char) is, buy definition 1.
while ( next != '\n' ) {

line = (char*) realloc ( line, (strlen(line) + 1) * sizeof(char) );
You are calling strlen on an array of char that isn't null terminated.
line [strlen(line)] = next;
You are calling strlen on an array of char that isn't null terminated.
next = fgetc (stream );
}

*string = (char*) malloc((strlen(line))*sizeof(char));
You are calling strlen on an array of char that isn't null terminated.

--
Ian Collins.
Feb 14 '07 #2

"Ian Collins" <ia******@hotmail.comschrieb im Newsbeitrag
news:53**************@mid.individual.net...
WStoreyII wrote:
>line = (char*) malloc (1*sizeof(char));
Why oh why are people still adding these extraneous casts? Not only
that, but sizeof(char) is, buy definition 1.
For several reasons: it is mentiond in lots of books about C and it is
required by C++
I admit that neither is a good reason (the books are just wrong and C++ is
OT here), but at least understandable. And a minor issue, there are more
important things to moan about, won't you think?

Bye, Jojo.
Feb 14 '07 #3
WStoreyII wrote:
the following code is supposed to read a whole line upto a new line
char from a file. however it does not work. it is producing weird
results. please help. I had error checking in there for mallocs and
ect, but i removed them to help me debug. thanks.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void freadl ( FILE *stream, char **string ) {

char next = fgetc ( stream );
fgetc() returns an int value. This is because, it has no way of
indicating failure within the range of a char value, since it could be
a legal. Hence it returns an out-of-band value, represented
symbolically as EOF. So you should test each invocation of fgetc(),
getc(), getchar() etc. like:

int next;
if((next = fgetc(stream)) == EOF) /* handle error */

or something similar.
char *line;

line = (char*) malloc (1*sizeof(char));
The casts are not needed in C. Do:
line = malloc(1 * sizeof *line);
while ( next != '\n' ) {

line = (char*) realloc ( line, (strlen(line) + 1) * sizeof(char) );
There're multiple error here. First, if realloc() happens to fail, you
overwrite the address of the original buffer with a null pointer
value, thus loosing access to it. You should always backup the address
of the buffer before attempting to reallocating it. Secondly, as
above, the cast is once again uneccessary.

Now coming to the main mistake. You're passing a unbounded array to
strlen(). strlen() is used to find the length of C strings and you
must supply it a nul terminated array. While all strings are arrays,
all arrays are not strings, i.e. nul terminated, as in this case.

I suggest increasing the buffer by a factor of two. You must keep
track of the size of the buffer yourself, presumably with a size_t
object.
line [strlen(line)] = next;
Same mistake. The buffer you're using is *not* storing a string.
You're just reading a sequence of characters. strlen() is the wrong
function to use. You have to keep track of the buffer length manually.
next = fgetc (stream );
}

*string = (char*) malloc((strlen(line))*sizeof(char));
No need for an unneccessary allocation here. Dynamically allocated
objects persist until they're free()'ed or until program termination.
Hence, all you need to do is to pass a pointer to the actual buffer
back to the calling function, along with the size of the line read
into the buffer.
strcpy (*string,line);
free(line);

}

int main ( int argc, char *argv[] ) {

FILE *fp;
fp = fopen ( "fread.c", "r" );
Check the return values of standard library functions. Just going
ahead assuming success is asking for difficult to find bugs.
char *str;
freadl ( fp , &str );

printf ( "str = %s, with size of %d\n", str, strlen (str) );

int i;

for ( i = 0; i < strlen (str); i++ ){

char now = str[i];
printf ( "chr = %c, # = %d\n", now,now);

}

}
The main mistake you're making is assuming that you can find out the
length of any object with strlen(). The latter only works on objects
terminated by a nul character, '\0'. For other objects, you'll have to
track their length by other methods.

Feb 14 '07 #4
WStoreyII wrote:
>
the following code is supposed to read a whole line upto a new line
char from a file. however it does not work. it is producing weird
results. please help. I had error checking in there for mallocs and
ect, but i removed them to help me debug. thanks.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void freadl ( FILE *stream, char **string ) {

char next = fgetc ( stream );
char *line;

line = (char*) malloc (1*sizeof(char));

while ( next != '\n' ) {

line = (char*) realloc ( line, (strlen(line) + 1) * sizeof(char) );
line [strlen(line)] = next;
next = fgetc (stream );
}

*string = (char*) malloc((strlen(line))*sizeof(char));
strcpy (*string,line);
free(line);

}

int main ( int argc, char *argv[] ) {

FILE *fp;
fp = fopen ( "fread.c", "r" );

char *str;
freadl ( fp , &str );

printf ( "str = %s, with size of %d\n", str, strlen (str) );

int i;

for ( i = 0; i < strlen (str); i++ ){

char now = str[i];
printf ( "chr = %c, # = %d\n", now,now);

}

}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void freadl(FILE *stream, char **string)
{
unsigned long counter = 0;
char *line = NULL;
int next = fgetc(stream);

do {
next = fgetc(stream);
if (next == EOF) {
free(line);
break;
}
++counter;
line = realloc(line, counter + 1);
if (line == NULL) {
puts("line == NULL");
exit(EXIT_FAILURE);
}
line[counter - 1] = (char)next;
} while (next != '\n');
line[counter - 1] = '\0';
*string = malloc(strlen(line) + 1);
if (*string == NULL) {
puts("*string == NULL");
} else {
strcpy(*string, line);
}
free(line);
}

int main (void)
{
char *str;
FILE *fp = fopen("fread.c", "r");

if (fp != NULL) {
freadl(fp , &str);
printf("str = %s, with length of %u\n",
str, (unsigned)strlen(str));
} else {
puts("fp == NULL");
}
return 0;
}
--
pete
Feb 14 '07 #5
On Feb 14, 5:06 am, pete <pfil...@mindspring.comwrote:
WStoreyII wrote:
the following code is supposed to read a whole line upto a new line
char from a file. however it does not work. it is producing weird
results. please help. I had error checking in there for mallocs and
ect, but i removed them to help me debug. thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void freadl ( FILE *stream, char **string ) {
char next = fgetc ( stream );
char *line;
line = (char*) malloc (1*sizeof(char));
while ( next != '\n' ) {
line = (char*) realloc ( line, (strlen(line) + 1) * sizeof(char) );
line [strlen(line)] = next;
next = fgetc (stream );
}
*string = (char*) malloc((strlen(line))*sizeof(char));
strcpy (*string,line);
free(line);
}
int main ( int argc, char *argv[] ) {
FILE *fp;
fp = fopen ( "fread.c", "r" );
char *str;
freadl ( fp , &str );
printf ( "str = %s, with size of %d\n", str, strlen (str) );
int i;
for ( i = 0; i < strlen (str); i++ ){
char now = str[i];
printf ( "chr = %c, # = %d\n", now,now);
}
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void freadl(FILE *stream, char **string)
{
unsigned long counter = 0;
char *line = NULL;
int next = fgetc(stream);

do {
next = fgetc(stream);
if (next == EOF) {
free(line);
break;
}
++counter;
line = realloc(line, counter + 1);
if (line == NULL) {
puts("line == NULL");
exit(EXIT_FAILURE);
}
line[counter - 1] = (char)next;
} while (next != '\n');
line[counter - 1] = '\0';
*string = malloc(strlen(line) + 1);
if (*string == NULL) {
puts("*string == NULL");
} else {
strcpy(*string, line);
}
free(line);

}

int main (void)
{
char *str;
FILE *fp = fopen("fread.c", "r");

if (fp != NULL) {
freadl(fp , &str);
printf("str = %s, with length of %u\n",
str, (unsigned)strlen(str));
} else {
puts("fp == NULL");
}
return 0;}

--
pete

thanks for all of the help. i will try these out later. as far as
the cast goes and using sizeof(char). i am new to c (obviously) and
everything that i have read so far has said to use these methods. so
as with anything there are those who are strict and those who are
not. i have actually got compiler warnings though for not having the
casts on malloc.

thanks again for your help.

Feb 14 '07 #6
WStoreyII wrote:
thanks for all of the help. i will try these out later. as far as
the cast goes and using sizeof(char). i am new to c (obviously) and
everything that i have read so far has said to use these methods. so
as with anything there are those who are strict and those who are
not. i have actually got compiler warnings though for not having the
casts on malloc.

thanks again for your help.
BTW: Is this for an intended purpose? If not, you can just use fgets().
Feb 14 '07 #7
WStoreyII said:
i have actually got compiler warnings though for not having the
casts on malloc.
That is almost certainly caused by one of two problems:

a) you forgot to #include <stdlib.h>

b) you're using a C++ compiler, not a C compiler

If it's a), then add the include. If it's b), you have two reasonable
courses of action: i) use a C compiler instead, or ii) write in C++
instead.

If you choose to write in C++ instead, you should probably consider
malloc to be obsolete, and use new, new[], or std::vector instead. If
you choose the C++ route, please direct further discussions thereof to
comp.lang.c++ rather than this newsgroup.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Feb 14 '07 #8
WStoreyII wrote:
i have actually got compiler warnings though for not having the
casts on malloc.
The typical cause of that warning is the failure to write
#include <stdlib.h>
prior to the call to malloc.
The compiler then assumes that malloc returns type int,
and then the warning is about attempting
to assign an integer type value to a pointer.

That's why casting the return value of malloc is bad.
It tends to conceal the real error,
which is the failure to include stdlib.h.

--
pete
Feb 14 '07 #9
Joachim Schmitz wrote, On 14/02/07 09:45:
"Ian Collins" <ia******@hotmail.comschrieb im Newsbeitrag
news:53**************@mid.individual.net...
>WStoreyII wrote:
>>line = (char*) malloc (1*sizeof(char));
Why oh why are people still adding these extraneous casts? Not only
that, but sizeof(char) is, buy definition 1.
For several reasons: it is mentiond in lots of books about C and it is
required by C++
I admit that neither is a good reason (the books are just wrong and C++ is
OT here), but at least understandable. And a minor issue, there are more
important things to moan about, won't you think?
As shown by a later reply of WStoreyII's the cast was actually hiding
one of a couple of serious errors. The errors being either using a
compiler in C++ mode for C or failing to include stdlib.h when needed.
So the comment about the cast was important and has shown up a serious
error. It is because of the hiding of serious errors that most people
here recommend against casting the result of malloc (or any other cast
that is not actually required).
--
Flash Gordon
Feb 14 '07 #10
WStoreyII wrote:
>
.... snip ...
i have actually got compiler warnings though for not having the
casts on malloc.
Unless your compiler is faulty, those are probably due to failing
to #include <stdlib.h>, and have nothing to do with casts.

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

"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

Feb 14 '07 #11
On 14 Feb 2007 05:46:37 -0800, "WStoreyII" <WS*******@gmail.com>
wrote:

snip ~ 100 lines
>

thanks for all of the help. i will try these out later. as far as
the cast goes and using sizeof(char). i am new to c (obviously) and
everything that i have read so far has said to use these methods. so
as with anything there are those who are strict and those who are
not. i have actually got compiler warnings though for not having the
casts on malloc.

thanks again for your help.
While quoting context is important, there is no need to quote a
hundred lines just to say thank you..
Remove del for email
Feb 15 '07 #12
On Feb 14, 9:50 am, CBFalconer <cbfalco...@yahoo.comwrote:
WStoreyII wrote:

... snip ...
i have actually got compiler warnings though for not having the
casts on malloc.

Unless your compiler is faulty, those are probably due to failing
to #include <stdlib.h>, and have nothing to do with casts.

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

"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

as you see in the original code above i did not fail to include
stdlib.h and gcc is my compiler and is one of the most popular c
compilers.

Feb 15 '07 #13
WStoreyII said:
On Feb 14, 9:50 am, CBFalconer <cbfalco...@yahoo.comwrote:
>WStoreyII wrote:

... snip ...
i have actually got compiler warnings though for not having the
casts on malloc.

Unless your compiler is faulty, those are probably due to failing
to #include <stdlib.h>, and have nothing to do with casts.

as you see in the original code above i did not fail to include
stdlib.h and gcc is my compiler and is one of the most popular c
compilers.
gcc definitely gets this right (does *not* produce a diagnostic message
when malloc is properly used), so I can only presume you are using gcc
in C++ mode.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Feb 15 '07 #14
WStoreyII wrote:
CBFalconer <cbfalco...@yahoo.comwrote:
>WStoreyII wrote:

... snip ...
>>i have actually got compiler warnings though for not having the
casts on malloc.

Unless your compiler is faulty, those are probably due to failing
to #include <stdlib.h>, and have nothing to do with casts.

as you see in the original code above i did not fail to include
stdlib.h and gcc is my compiler and is one of the most popular c
compilers.
gcc is many compilers. If you don't run it correctly it could be a
C++ compiler, which is a faulty C compiler.

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

"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
Feb 15 '07 #15

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

Similar topics

2
by: les_ander | last post by:
Hi, matlab has a useful function called "textread" which I am trying to reproduce in python. two inputs: filename, format (%s for string, %d for integers, etc and arbitary delimiters) ...
3
by: Eric Theil | last post by:
I'm at my wit's end with this one. Within an xsl:if test, I'm not able to get 2 variables to properly evaluate if one of them is wrapped within a string function. <!-- This works --> <xsl:if...
4
by: Mark | last post by:
Hi.. I have a c# class that i'm using to implement some extension functions and one of those functions is a simple push/pop stack. I made the c# code fairly generic, taking and returning objects...
5
by: Pete | last post by:
I having a problem reading all characters from a file. What I'm trying to do is open a file with "for now" a 32bit hex value 0x8FB4902F which I want to && with a mask 0xFF000000 then >> right...
12
by: Clifford Stern | last post by:
In a function that returns two values, how do you read them? Consider the following function: int addsub(int x,int y) {int a,b; a=x+y; b=x-y; return(a,b);} trying to read the results, for...
5
by: mike | last post by:
If I have a document like: <script> function mike_test() {alert('hi');} </script> <iframe src="blank.html" id="my_iframe1"> </iframe> and in blank.html I have:
6
by: placid | last post by:
Hi all, I have been looking into non-blocking read (readline) operations on PIPES on windows XP and there seems to be no way of doing this. Ive read that you could use a Thread to read from the...
1
by: Arpan | last post by:
The contents of a text file are as follows: The Quick Brown Fox Jumped Over The Lazy Dog. Note that there isn't any space at the end of each of the 3 lines. Now when I do this:
14
by: Nickolay Ponomarev | last post by:
Hi, Why does http://www.jibbering.com/faq/ uses new Function constructor instead of function expressions (function(...) { ... }) when defining new functions? E.g. for LTrim and toFixed. Is the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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: 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:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.