strange behaviour

Discussion in 'C Programming' started by gribouille, Oct 15, 2006.

  1. gribouille

    gribouille Guest

    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 ?
    gribouille, Oct 15, 2006
    #1
    1. Advertising

  2. gribouille

    Ico Guest

    gribouille <> wrote:

    > 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.

    --
    :wq
    ^X^Cy^K^X^C^C^C^C
    Ico, Oct 15, 2006
    #2
    1. Advertising

  3. gribouille

    gribouille Guest

    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
    gribouille, Oct 15, 2006
    #3
  4. gribouille

    Ico Guest

    gribouille <> wrote:

    > 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]

    --
    :wq
    ^X^Cy^K^X^C^C^C^C
    Ico, Oct 15, 2006
    #4
  5. gribouille

    gribouille Guest

    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;

    }
    }
    gribouille, Oct 15, 2006
    #5
  6. 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);
    >



    > i=0;


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


    --------------

    I suggest you change your memory allocation scheme to get the size of
    the file first, then do just one malloc() to get that much memory.
    Ancient_Hacker, Oct 15, 2006
    #6
  7. gribouille

    gribouille Guest

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

    >
    >
    >> i=0;

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

    >
    > --------------
    >
    > I suggest you change your memory allocation scheme to get the size of
    > the file first, then do just one malloc() to get that much memory.
    >
    gribouille, Oct 15, 2006
    #7
  8. gribouille

    CBFalconer Guest

    gribouille wrote:
    >
    > 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.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
    CBFalconer, Oct 15, 2006
    #8
  9. gribouille

    Ico Guest

    gribouille <> wrote:

    > 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.


    --
    :wq
    ^X^Cy^K^X^C^C^C^C
    Ico, Oct 15, 2006
    #9
  10. "Ancient_Hacker" <> writes:
    > 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.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Oct 15, 2006
    #10
  11. On Sun, 2006-10-15 at 19:31 +1000, gribouille wrote:
    > 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.

    --
    Andrew Poelstra <http://www.wpsoftware.net>
    For email, use 'apoelstra' at the above site.
    Andrew Poelstra, Oct 15, 2006
    #11
  12. Andrew Poelstra wrote:
    > On Sun, 2006-10-15 at 19:31 +1000, gribouille wrote:
    >
    >>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.


    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
    Yevgen Muntyan, Oct 15, 2006
    #12
  13. gribouille

    Bart Guest

    Yevgen Muntyan wrote:
    > Andrew Poelstra wrote:
    > > On Sun, 2006-10-15 at 19:31 +1000, gribouille wrote:
    > > 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?


    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.
    Bart, Oct 15, 2006
    #13
  14. On Sun, 2006-10-15 at 18:52 +0000, Yevgen Muntyan wrote:
    > Andrew Poelstra wrote:
    > > 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?


    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.

    --
    Andrew Poelstra <http://www.wpsoftware.net/projects/>
    Andrew Poelstra, Oct 15, 2006
    #14
  15. Yevgen Muntyan <> writes:
    > Andrew Poelstra wrote:
    >> On Sun, 2006-10-15 at 19:31 +1000, gribouille wrote:
    >>
    >>>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.

    >
    > 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.

    --
    Keith Thompson (The_Other_Keith) <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.
    Keith Thompson, Oct 16, 2006
    #15
  16. gribouille

    Chris Torek Guest

    In article <4532238f$0$11974$>
    gribouille <> wrote:
    [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.

    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.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Oct 16, 2006
    #16
  17. gribouille

    CBFalconer Guest

    Chris Torek wrote:
    > gribouille <> wrote:
    >
    > [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 :)

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
    CBFalconer, Oct 16, 2006
    #17
  18. gribouille

    Steven Kirby Guest

    gribouille wrote:
    > 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!
    Steven Kirby, Oct 16, 2006
    #18
  19. Steven Kirby said:

    > gribouille wrote:
    >> 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.


    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.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
    Richard Heathfield, Oct 16, 2006
    #19
  20. gribouille

    Richard Bos Guest

    Steven Kirby <> wrote:

    > gribouille wrote:
    > > 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.


    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
    Richard Bos, Oct 16, 2006
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Antonio

    Strange encoding behaviour

    Antonio, Dec 29, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    415
    Antonio
    Dec 29, 2004
  2. Jan
    Replies:
    2
    Views:
    1,418
    Mike Treseler
    Dec 16, 2004
  3. David Cantin

    Strange behaviour with perl and apache

    David Cantin, Nov 3, 2003, in forum: Perl
    Replies:
    1
    Views:
    449
    Jim Gibson
    Nov 3, 2003
  4. Dennis Johansson
    Replies:
    1
    Views:
    491
    Dennis Johansson
    Aug 21, 2003
  5. Andy Chambers
    Replies:
    1
    Views:
    377
    Daniel Dyer
    May 14, 2007
Loading...

Share This Page