strange behaviour

G

gribouille

Hi,

via fgets() i create a array containing a text file.

fp = fopen(argv[1], "r");
while ((c = fgetc(fp)) != EOF) {
line[l] = c;


when i want to print it
while (i < w){
//printf("%c", bodytext);
i++;
}
it works, but if i intergrate a if(line=='\\') {...}
it print me some funny caracteres in the text

what happened ?
 
I

Ico

gribouille said:
via fgets() i create a array containing a text file.

fp = fopen(argv[1], "r");
while ((c = fgetc(fp)) != EOF) {
line[l] = c;

I see no fgets() in this snippet of code
when i want to print it
while (i < w){
//printf("%c", bodytext);
i++;
}


This does not print anything, since the line containing printf() is
commented out.
it works, but if i intergrate a if(line=='\\') {...}
it print me some funny caracteres in the text


Your code is incoherent, does not match your description and does not
compile. Please provide a complete and compiling program showing the
behaviour you see.
what happened ?

I can't tell from this description. Maybe others can.
 
G

gribouille

may be this one is better ...


FILE *fp;


line = (char *)malloc(2*sizeof(char));
bodytext = (char *)malloc(sizeof(char));
docwidth = (char *)malloc(sizeof(char));
//tag = (char *)malloc(sizeof(strlen(line)));

fp = fopen(argv[1], "r");
while ((c = fgetc(fp)) != EOF) {
line[l] = c;
allocation_memory(1); // realloc function
//printf("%c", line[l]);
l++;
}


fclose(fp);

i=0;
w = strlen(bodytext);
while (i < w){
printf("%c", bodytext);
i++;
}

realloc funtcion

if ((line = realloc(line, sizeOfLine))) {
/* realoc ok */
sizeOfLine = sizeOfLine++;
} else {

printf ("*** No Memory\n");
exit (1);
free (line);
}



// so if i put the condition in the while loop, it display some wierds
caractere
 
I

Ico

gribouille said:
may be this one is better ...

No, I don't mean to be picky, but it is not better. It still is not
complete and it still does not compile. Please provide a *complete* C
program which people can feed to their compiler without having to guess
what you mean from your snippets. Complete C programs #include the
headers they need, and provide at least a main() function.

[snipped code]
 
G

gribouille

this one is complete and compile, sorry about that i'm new on this forum ;-)

to test it just put text file in the commande line.
So it works well if i don't put the line
if (line == '\\'){ printf("hello");}



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *line;
void allocation_memory(int);

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

line = (char *)malloc(2*sizeof(char));
char c;
int i = 0;
int v = 0;
int l = 0;
int w = 0;

FILE *fp;
fp = fopen(argv[1], "r");
while ((c = fgetc(fp)) != EOF) {
line[l] = c;
allocation_memory(1);
l++;
}


fclose(fp);

i=0;
w = strlen(line);
while (i < w){
if (line == '\\'){
printf("hello");
}
printf("%c", line);
i++;
}
free(line);
}

void allocation_memory(int grade)
{

int sizeOfLine = 3;
int sizeOfbodytext = 2;
int sizeOfdocwidth = 2;
switch( grade )
{
case '1' : if ((line = realloc(line, sizeOfLine))) {
/* la réallocation s'est bien passée , l'affectation est
sûre: */
sizeOfLine = sizeOfLine++;
} else {

printf ("*** Mémoire insuffisante\n");
exit (1);
free (line);
}
// return NULL;
break;

}
}
 
A

Ancient_Hacker

Lots of things wrong with your code!
line = (char *)malloc(2*sizeof(char));
char c;
int i = 0;
int v = 0;
int l = 0;
int w = 0;

FILE *fp;
fp = fopen(argv[1], "r"); // you don't check to see if the fopen worked
while ((c = fgetc(fp)) != EOF) {
line[l] = c; // the letter "ell" is a poor name for a variable, looks too much line the digit "1"
allocation_memory(1); // reallocating a byte at a time is ridiculously slow
l++;
}


fclose(fp);


w = strlen(line); // you never put a terminating zero byte into line??
while (i < w){
if (line == '\\'){
printf("hello");
}

printf("%c", line);
i++;
}

void allocation_memory(int grade)
{

int sizeOfLine = 3; // this gets done EVERY time you call this function!
int sizeOfbodytext = 2;
int sizeOfdocwidth = 2;
switch( grade )
{
case '1' : if ((line = realloc(line, sizeOfLine))) {
/* la réallocation s'est bien passée , l'affectation est
sûre: */
sizeOfLine = sizeOfLine++; // useless, and redundant at the same time.
} else {

printf ("*** Mémoire insuffisante\n");
exit (1);
free (line);
}
// return NULL;
break;

}
}
 
G

gribouille

i won' t get the size till the end of the file, is there another way of
getting it ?

Ancient_Hacker a écrit :
Lots of things wrong with your code!
line = (char *)malloc(2*sizeof(char));
char c;
int i = 0;
int v = 0;
int l = 0;
int w = 0;

FILE *fp;
fp = fopen(argv[1], "r"); // you don't check to see if the fopen worked
while ((c = fgetc(fp)) != EOF) {
line[l] = c; // the letter "ell" is a poor name for a variable, looks too much line the digit "1"
allocation_memory(1); // reallocating a byte at a time is ridiculously slow
l++;
}


fclose(fp);


w = strlen(line); // you never put a terminating zero byte into line??
while (i < w){
if (line == '\\'){
printf("hello");
}

printf("%c", line);
i++;
}

void allocation_memory(int grade)
{

int sizeOfLine = 3; // this gets done EVERY time you call this function!
int sizeOfbodytext = 2;
int sizeOfdocwidth = 2;
switch( grade )
{
case '1' : if ((line = realloc(line, sizeOfLine))) {
/* la réallocation s'est bien passée , l'affectation est
sûre: */
sizeOfLine = sizeOfLine++; // useless, and redundant at the same time.
} else {

printf ("*** Mémoire insuffisante\n");
exit (1);
free (line);
}
// return NULL;
break;

}
}

 
C

CBFalconer

gribouille said:
i won' t get the size till the end of the file, is there another way of
getting it ?

Don't top-post. Your answer belongs after the /snipped/ material
you quote (or possibly intermixed). The snipping removes any
quotes not relevant to your reply.
 
I

Ico

gribouille said:
this one is complete and compile, sorry about that i'm new on this
forum ;-)

No problem, but you'll see people are much more eager to help you when
you post some code that is complete and actually runs.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *line;
void allocation_memory(int);

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

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

Hint: No need to cast the return value of malloc.
char c;
int i = 0;
int v = 0;
int l = 0;
int w = 0;

FILE *fp;
fp = fopen(argv[1], "r");

Hint: You use argv[1] here, without checking if there are actually
additional arguments supplied to the program. Might crash.

Hint: You don't check the value of fp after the fopen call. This causes
undefined behaviour when you use the variable. Might crash.
while ((c = fgetc(fp)) != EOF) {
line[l] = c;
allocation_memory(1);
l++;
}


fclose(fp);

i=0;
w = strlen(line);

This is very wrong: you are using strlen to find out the length of the
string, but your buffer of characters is not terminated by a '\0', which
does not make it a valid C-string. the strlen function is very likely to
return a value that is larger then the number of characters you have
allocated previously, thus your code is reading memory you do not own.
The fix would be to make sure the last character in your string is
always a '\0'
while (i < w){
if (line == '\\'){
printf("hello");
}
printf("%c", line);
i++;
}
free(line);


Hint: main() should return and int
}

void allocation_memory(int grade)
{

int sizeOfLine = 3;
int sizeOfbodytext = 2;
int sizeOfdocwidth = 2;
switch( grade )
{
case '1' : if ((line = realloc(line, sizeOfLine))) {
/* la réallocation s'est bien passée , l'affectation est
sûre: */
sizeOfLine = sizeOfLine++;

This line yields undefined behaviour, the proper syntax is either
"sizeOfLine = sizeOfLine + 1;" or "sizeOfLine ++;"
} else {

printf ("*** Mémoire insuffisante\n");
exit (1);
free (line);
}
// return NULL;
break;

}
}

There might be more problems with this code I, but these ones I spotted
in the first seconds.
 
K

Keith Thompson

Ancient_Hacker said:
Lots of things wrong with your code!
line = (char *)malloc(2*sizeof(char));
char c;
int i = 0;
int v = 0;
int l = 0;
int w = 0;

FILE *fp;
fp = fopen(argv[1], "r"); // you don't check to see if the fopen worked
while ((c = fgetc(fp)) != EOF) {
line[l] = c; // the letter "ell" is a poor name for a variable, looks too much line the digit "1"
allocation_memory(1); // reallocating a byte at a time is ridiculously slow
[snip]

If you're going to comment on code, please write your comments
separately, as new text, not as actual comments added to the code.
It's impossible to tell, without going back to the previous article,
whether your comments were in the originally posted code or not.

And "//" comments on Usenet are ill-advised, especially with very long
lines.
 
A

Andrew Poelstra

may be this one is better ...

Hardly. You need to post something /compilable/.
FILE *fp;


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

Four things:
1) Never case the return value of malloc(). It hides the fact that you
didn't #include <stdlib.h>.
2) Never use sizeof on a type name, at least at this point in your C
programming. Use (sizeof *line) if you must.
3) sizeof(char) is 1 by definition. You can eliminate it, thus improving
clarity.
4) Don't use tabs on Usenets. They'll display wrong, be filtered out, or
display correctly. In any case, it's bad. Use 2 or 4 spaces instead.

So,
line = malloc(2);

See how much nicer that is?
bodytext = (char *)malloc(sizeof(char));
docwidth = (char *)malloc(sizeof(char));
//tag = (char *)malloc(sizeof(strlen(line)));

Two things:
1) // comments aren't supported in C90, which is what 99.9% of people
use. Use /*...*/ comments instead.
2) sizeof(strlen(line)) == sizeof (size_t), probably not what you want.
fp = fopen(argv[1], "r");
while ((c = fgetc(fp)) != EOF) {
line[l] = c;
allocation_memory(1); // realloc function
//printf("%c", line[l]);
l++;
}

What does that brace close? Please format correctly.

<snipped other unreadable code>

Fix your formatting and the aforementioned problems, and then we'll be
able to fix all the UB and logic errors in your code.
 
Y

Yevgen Muntyan

Andrew said:
Hardly. You need to post something /compilable/.




Four things:
1) Never case the return value of malloc(). It hides the fact that you
didn't #include <stdlib.h>.
2) Never use sizeof on a type name, at least at this point in your C
programming. Use (sizeof *line) if you must.

Why? I heard people prefer "sizeof *var" because it's nicer or whatever,
but why "Never use sizeof on a type name"? Is it really such an advanced
thing, and only mature programmers can use it correctly?

Regards,
Yevgen
 
B

Bart

Yevgen said:
Why? I heard people prefer "sizeof *var" because it's nicer or whatever,
but why "Never use sizeof on a type name"? Is it really such an advanced
thing, and only mature programmers can use it correctly?

The reason is that you should factor out every variable aspect of your
program so that it appears only in one place.

Suppose you have:

int* var;

var = malloc(n * sizeof(int));

Now, if you want to change the type of 'var', for example, to long you
need to change it in two places. On the other hand:

int* var;

var = malloc(n * sizeof *var);

Here you only need to change the declaration.


Regards,
Bart.
 
A

Andrew Poelstra

Why? I heard people prefer "sizeof *var" because it's nicer or whatever,
but why "Never use sizeof on a type name"? Is it really such an advanced
thing, and only mature programmers can use it correctly?

It's a cautious way to program; in almost all cases using sizeof on an
object instead of a type will cause no problems, and will protect the
code against future changes.

It could be considered a style issue, I suppose, but I think that it's
more than that.

As for sizeof(type), it's only really necessary in a few very special
situations which may be considered advanced.
 
K

Keith Thompson

Yevgen Muntyan said:
Why? I heard people prefer "sizeof *var" because it's nicer or whatever,
but why "Never use sizeof on a type name"? Is it really such an advanced
thing, and only mature programmers can use it correctly?

Think about why you want to compute the size of something. If you
want the size of a type, it's almost always because you need the size
of some object or expression of that type. And if, as the code is
maintained, the type of that object or expression changes, you won't
need to change code if you applied sizeof directly to the object or
expression rather than to the type.
 
C

Chris Torek

gribouille said:
allocation_memory(1); [more snippage]
void allocation_memory(int grade) { [still more snippage]
switch( grade )
{
case '1' :

Others have pointed out several earlier problems. Another one occurs
here: you pass the integer constant 1 to allocation_memory(), and
then test for the character-constant '1', which is probably 49 or
241 (depending on whether your machine uses ASCII or EBCDIC), but
in any case is definitely not 1.

There is no other "case", and no "default", so the switch statement
falls through to the end, which is also the end of the function, and
the call is a no-op.
 
C

CBFalconer

Chris said:
[much snippage]
allocation_memory(1); [more snippage]
void allocation_memory(int grade) { [still more snippage]
switch( grade )
{
case '1' :

Others have pointed out several earlier problems. Another one
occurs here: you pass the integer constant 1 to allocation_memory(),
and then test for the character-constant '1', which is probably 49
or 241 (depending on whether your machine uses ASCII or EBCDIC), but
in any case is definitely not 1.

I think it is on MIX :)
 
S

Steven Kirby

gribouille said:
i won' t get the size till the end of the file, is there another way of
getting it ?

There certainly is! Use fseek() to set the file pointer to the end of
the file, then ftell() to return the pointer's position. This'll give
you the size of the file. The rewind() function sets the file pointer to
the start of the file again - essential if you're going to read from it.
Finally, instead of reading each byte with fgetc(), you can read an
entire chunk of data with fread().

A snippet, for demonstration:

-------------------------
FILE *fp;
char *myfile;
long filesize;

if(! (fp = fopen(argv[1], "rb")) )
{
// failed to open file
return -1;
}

fseek(fp, 0L, SEEK_END);
filesize = ftell(fp);
rewind(fp);

myfile = (char*)malloc(filesize * sizeof(char));

fread(myfile, filesize, 1, fp);
-------------------------

Note that this example only allocates enough space for the file, not for
a terminating null. You'll need to add that if you're going to display
the file contents as a string, for example.

Good luck!
 
R

Richard Heathfield

Steven Kirby said:
There certainly is! Use fseek() to set the file pointer to the end of
the file, then ftell() to return the pointer's position. This'll give
you the size of the file.

This technique often works, but strictly speaking it's not a portable
technique, failing for one reason on text streams and for another on binary
streams. The comp.lang.c archives are packed to the gunwales with
discussions of this issue. A Google Groups search may prove informative.
 
R

Richard Bos

Steven Kirby said:
There certainly is! Use fseek() to set the file pointer to the end of
the file, then ftell() to return the pointer's position. This'll give
you the size of the file.

Except that it may not. For binary streams fseek() with SEEK_END isn't
required to work, and for text streams ftell() need not give you a count
in bytes, chars, or anything else that makes sense to a human; so either
way, this method may work, but it's not guaranteed.
myfile = (char*)malloc(filesize * sizeof(char));

Oh, and don't cast malloc(). It's not necessary, and all unnecessary
casts are the work of Nyarlathotep; and in fact it may hide the error of
not having a declaration in scope. Also, but less seriously, sizeof
(char) is guaranteed to be 1.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Working with files 1
URGENT 1
strange behaviour of the program. 8
write error 13
Command Line Arguments 0
strtod strange behaviour 9
Opening a file of user's choice 11
comparison error 12

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top