Thread: arrays, file access question..a little bit of everything

  1. #1
    Registered User white's Avatar
    Join Date
    Nov 2004
    Posts
    39

    arrays, file access question..a little bit of everything

    Well i did make a quick search throughout the forum for an answer ..iam sure there is one somewhere..maybe iam not so good at searching...anyway here is my question...I think iam fairly good at c++ but lately i've decide to learn c as well...why not? so i've decided to port one of my programms..but iam stuck (it is obvious i suppose) ok..here is the code.


    Code:
    #include <stdio.h>
    
    int linesoffile(FILE *stream)
    {
    	printf("file read\n");
    	char x[12],y[12],z[12];
    	int i=0;
    	char *forpop = "%s %s %s\n";
    	while (fscanf (stream, forpop, x, y, z) == 3)
    	{
    	printf("x:%s, y:%s, z:%s\n", x, y, z);
    	i++;
    	}
    	printf("the number of coordinates in the file are: %d", i);
    	return i;
    }
    int main (int argc, const char * argv[])
    {
       FILE *stream = fopen("stone2000.xyz", "r");
       
       if(!stream)
       {
       printf("file open failed");
       }
       
       int i = linesoffile(stream);
       printf("\n%d ", i);
       float x[i], y[i], z[i], b;
       int g;
    	char * del = "%f %f %f\n";
    
    	for ( g = 0; i > g; g++);
    	{
    	b = fscanf (stream, del, x[g], y[g], z[g]);
    	g++;
    	}
    //testing the arrays
    	printf("%f %f %f %d", x[0], y[45], z[78], g);
       
       fclose(stream);
    	return 0;
    }
    ok this piece of code displays the file correctly but fills the arrays with zeros...so i've thought that i need to rewind the stream (or something) but it still doesn't work. if i access the linesoffile function the first time i get the correct result but not the second etc...i reckon it is the same problem..

    any ideas?

    ps. i don't think that it matters but iam using a mac

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Welcome to the forums!

    Yes, your suspicions are correct. You need to reposition the file pointer at the beginning of the file. You use the fseek() function to position the file pointer.
    Code:
    fseek(stream, 0, SEEK_SET); /* Set the file pointer to the beginning of the file. */
    --
    Code:
    	char x[12],y[12],z[12];
    	int i=0;
    	char *forpop = "%s %s %s\n";
    	while (fscanf (stream, forpop, x, y, z) == 3)
    This is not a safe way to use fscanf(). If one of the strings is more than 11 characters long your program will crash or be compromised. You need to set maximum string lengths in the format string.
    Code:
    	char x[12],y[12],z[12];
    	int i=0;
    	char *forpop = "%.11s %.11s %.11s\n";
    	while (fscanf (stream, forpop, x, y, z) == 3)
    --
    Code:
       float x[i], y[i], z[i], b;
    For this to compile, you must be using a modern C99 compatible compiler. However, you should be aware that this will not compile on the many compilers that do not yet implement C99. For these compilers the size of an array must be a compile-time constant. To create dynamic arrays with these compilers you typically use malloc() to allocate memory at run-time.
    --
    Code:
    	b = fscanf (stream, del, x[g], y[g], z[g]);
    You need to give fscanf the address of float variables so it can put values in rather than float values themselves. Remember, there is no such thing as pass by reference in C.
    Code:
    	b = fscanf (stream, del, &x[g], &y[g], &z[g]);
    --
    If you are still having troubles after implementing these fixes, please post a sample of the input file as well as a sample of the output you are getting.

  3. #3
    Registered User white's Avatar
    Join Date
    Nov 2004
    Posts
    39
    Well it does work now, but there is still something that bothers me a little bit. The file is displayed correctly but when i tried to use printf to display the arrays the last digits of the values where different.

    the input file is like this:

    1024.963811 1007.437779 27.123941
    1025.615130 1006.869910 27.206927
    1025.266478 1007.126469 27.221993
    and the output float values look like this

    1024.963867 1007.437805 27.123941
    1025.615112 1006.869934 27.206926
    1025.266479 1007.126465 27.221992
    the last digits differ...maybe is the float's accuracy..maybe i should try double..

    thank you

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Your C needs a C99 or C++ compiler to compile it.

    > when i tried to use printf to display the arrays the last digits of the values where different.
    Welcome to the world of floating point numbers.
    http://cch.loria.fr/documentation/IEEE754/
    David Goldberg's paper is worth a read even if you don't get all the detail

    > maybe is the float's accuracy..maybe i should try double..
    Yes, that would move the problem from the 6th digit to the 15th digit.

  5. #5
    Registered User
    Join Date
    Apr 2004
    Posts
    210
    Quote Originally Posted by Salem
    Your C needs a C99 or C++ compiler to compile it.
    Maybe slightly offtopic, but do you think the use of C99 should be discouraged (considering it's almost 2005 now)?
    I'm asking because C99 allows more "elegant" code in some situations and I was thinking about changing some code of mine because of that.
    main() { int O[!0<<~-!0]; (!0<<!0)[O]+= ~0 +~(!0|!0<<!0); printf("a function calling "); }

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > but do you think the use of C99 should be discouraged
    Well there are only two or three compilers in the world which can even begin to claim compliance with C99.

    Half the people who show up here are still using TC2.01 for heavens sake, which isn't even C89 never mind C99.

    The decision to use C99 is fine by me, but I think it's still important to highlight the differences so that people are at least making an informed choice before they start complaining that "x" doesn't work all of a sudden.

  7. #7
    Registered User white's Avatar
    Join Date
    Nov 2004
    Posts
    39
    Well it compiled so i suppose mac's compiler (xcode) does support C99. I using a mac for no more than 4 months now...and i still have a lot to learn on specific api but as i understood most of the applications are written in c.

    I did take a look on the link Salem and I did some more investigation on my own...thanks for showing me the way...

    I still have a lot of questions ...but i like to post them only when iam fed up and cannot find my way out.

    thanks for everything

    ps. i think i will like this forum a lot

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > for ( g = 0; i > g; g++);
    Heh, another problem
    Remove the ; from the end of this line - it just makes the for loop do nothing a number of times.

    Compiler testing
    Code:
    #include <stdio.h>
    int main ( ) {
        printf( "Size=%lu\n", (unsigned long)sizeof('a') );
        return 0;
    }
    What does this program print when you run it?

  9. #9
    Registered User white's Avatar
    Join Date
    Nov 2004
    Posts
    39
    well i knew about the
    Code:
    for ( g = 0; i > g; g++);
    I had a reason for putting it there...I just forgot to delete it when i made the post...stupid me...anyway..

    this program prints

    Size=4
    if you care to explain I would be grateful
    thanks

  10. #10
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by white
    Well it does work now, but there is still something that bothers me a little bit. The file is displayed correctly but when i tried to use printf to display the arrays the last digits of the values where different.

    the input file is like this:



    and the output float values look like this



    the last digits differ...maybe is the float's accuracy..maybe i should try double..

    thank you
    If your system and compiler uses 32-bit floats (like most do these days, I think), they are only good for six or seven significant digits. Change float to double (and in your scanf format, use %lf instead of %f). This will handle about 15 or 16 significant digits.

    Regards,

    Dave
    Last edited by Dave Evans; 11-26-2004 at 05:40 PM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > if you care to explain I would be grateful
    Well when compiled as C, it prints the same answer as you would get for printing the size of an int, which on most commonly available machines is 4

    Compiled as C++, the answer is the same as sizeof char, which is always 1

    Just checking that you're actually using a C compiler, and not a C++ compiler without realising it

  12. #12
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >> Your C needs a C99 or C++ compiler to compile it. <<
    Code:
       float x[i], y[i], z[i], b;
    This will not compile in C++.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 01-08-2009, 12:15 PM
  2. Device Register Access
    By jacob12 in forum C Programming
    Replies: 35
    Last Post: 10-14-2008, 10:51 AM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. archive format
    By Nor in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 08-05-2003, 07:01 PM