Like Tree3Likes

Taking the mean of an array, and counting the 0 values of an array.

This is a discussion on Taking the mean of an array, and counting the 0 values of an array. within the C Programming forums, part of the General Programming Boards category; Hey again chaps! So, I'm still working on the same piece of work; literally just fell asleep for an hour ...

  1. #1
    Registered User
    Join Date
    Jun 2012
    Posts
    17

    Taking the mean of an array, and counting the 0 values of an array.

    Hey again chaps!
    So, I'm still working on the same piece of work; literally just fell asleep for an hour and a half after trying to take a 10 minute nap...

    Again, I'm making a program which opens a txt file, with integer numbers stored as follows:
    0
    888
    687687687
    7676

    I've managed to successfully open the file, put it into an array and print the array (Thank you for the help on that one! )
    But I also need to take the mean, RMS and count the number of 0 values in the txt file.
    I think that once I have the mean, doing the RMS will be fairly easy; however I can't quite get it to work:

    Code:
    void mvals()          
    {
         printf("Mean of the values contained within the txt file:\n\n");
         int numint, i=0, n=0, sum, mean, numbarr[100];
         rewind(FPTR);
         while((numint = fgetc(FPTR)) != EOF)
         {     
              i++;
         }
         n=i;
         i=0;
         rewind(FPTR);
         while((numint = fgetc(FPTR)) != EOF && i>=0 && i<=n)
         {
               numbarr[i]=numint;
               sum=sum+numbarr[i];
               i++;          
         }
         printf("Sum = %d\n", sum);
         mean =sum / n;
         printf("Mean = %d\n\n", mean);        
    }
    I've got a feeling it may still be to do with my limited knowledge of arrays, which I have read up on since the morning! :P

    Also, my zero value counter outputs 0, for a txt file that clearly has 3 zero values! Seems ironic...
    Here's the code:

    Code:
    void cvals()
    {
         printf("Number of 0 values contained within the txt file:\n\n");
         int numint, i=0, n=0, z=0, numbarr[100];
         rewind(FPTR);
         while((numint = fgetc(FPTR)) != EOF)
         {     
              i++;
         }
         n=i;
         i=0;
         rewind(FPTR);
         while((numint = fgetc(FPTR)) != EOF && i>=0 && i<=n)
         {
               numbarr[i]=numint;
               if (numbarr[i]==0)
               {
                          z=z+1;
               }
               i++;          
         }
         printf("%d\n\n",z);        
         main();     
    }
    Once again, any help is MUCH appreciated! Getting to the point in the day where I am gradually getting drawn to the idea of whiskey, or the gfs house.. But this assignment was due on Thursday. Gah... Not to self: Never miss programming lectures!!!

    Cheers,
    Will

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,936
    You did not give sum an initial value.

    Also, by using fgetc only, you will not be parsing numbers, but rather just reading characters.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    Hmm, can you suggest a file command that parses numbers instead? I was getting away with it before for printing values, but I guess for arithmetic I can't, unless I convert it with a command?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,936
    I suggest that you implement these functions:
    Code:
    size_t read_numbers(FILE *fp, int numbers[], size_t max_size);
    void print_numbers(FILE *fp, int numbers[], size_t size);
    double compute_mean(int numbers[], size_t size);
    double compute_rms(int numbers[], size_t size);
    size_t count_0s(int numbers[], size_t size);
    So, you open the file to get the FILE pointer. You declare an array of ints of some max_size (in your example, 100). Then you call read_numbers to read the numbers from the file into the array of ints, returning the number of numbers read. Now, you can confirm what was read by printing the array by calling print_numbers.

    After you have tested and are reasonably certain that read_numbers and print_numbers work, try implementing compute_mean or count_0s. Notice that these functions just operate on the array and have nothing to do with the file. You would presumably have closed the file before calling these functions.

    Quote Originally Posted by Williham
    Hmm, can you suggest a file command that parses numbers instead?
    Given your file format, you can get away with using fscanf and the %d format specifier.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    Thanks a lot, I'll give that a try.

  6. #6
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    Still no luck..
    This is the count 0 function that I'm currently working on:

    Code:
    size_t cvals()
    {
           
         printf("Number of 0 values contained within the txt file:\n\n");
         int numint, i=0, n=0, z=0, numbarr[100];
         rewind(fptr);
         while((numint = fgetc(fptr)) != EOF)
         {     
              i++;
         }
         n=i;
         i=0;
         rewind(fptr);
         while((numint = fscanf(fptr,"%d")) != EOF && i>=0 && i<=n)
         {
               numbarr[i]=numint;
               if (numbarr[i]==0)
               {
                          z=z+1;
               }
               i++;
         }
         printf("%d\n\n",z);        
         main();     
    }
    Which compiles OK, but freezes after printing the title.

    I changed the FPTR pointer to fptr, as I was told it's better to keep it lower case in another thread.
    Also, from what you said earlier laserlight,I'm guessing that the fscanf generally makes it run smoother, as well as allowing me to specify the format of the numbers.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,936
    Quote Originally Posted by Williham
    This is the count 0 function that I'm currently working on:
    Your function is completely wrong in its approach. A function should do one thing and do it well. Your cvals function does way too many things.

    Follow my approach. Start by making sure that you can read into the array correctly and print the array to stdout. Write a function to only count the 0s in the array and return that count. Stop using rewind here as you don't need it since you are reading into an array.

    Also, do not call the main function. You should be looping instead.

    Quote Originally Posted by Williham
    Also, from what you said earlier laserlight,I'm guessing that the fscanf generally makes it run smoother, as well as allowing me to specify the format of the numbers.
    You are using fgetc to try and count the number of numbers in the file. What you really ended up doing is counting the number of characters in the file. Unfortunately, because you did not test to see if you are really reading into the file correctly, you did not notice this. Rather, you should have used fscanf in a single loop, counting the number of numbers read as you loop. Oh, and you need to do things step by step. Write one part, compile and run to test if it works. If it doesn't work, fix it. If it works, move to the next part.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    7,740
    Also, from what you said earlier laserlight,I'm guessing that the fscanf generally makes it run smoother, as well as allowing me to specify the format of the numbers.
    I gave you this link before in the other thread but here it is again.
    FAQ > How do I get a number from the user (C) - Cprogramming.com
    All of the methods in this article apply equally to getting numbers from files. I didn't explain that before, so maybe that's why you ignored it.

  9. #9
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    I thought it was part of your sig whiteflags! :P

    laserlight, thank you for your patience with a slow learner, who has a bad habit of trying to cut corners!
    Time to re write the program me-thinks.

  10. #10
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    I'm going to call it a day before my eyes fall out I think! Pick it up again tomorrow.
    Thanks again for the help, I can imagine I'll be back tomorrow! :P

  11. #11
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    Good morning! (if UK )

    I believe I've made a fair amount of progress since yesterday, as you suggested laserlight, I've created a separate function to read the numbers and place them into an array; now I'm back to getting the print_numbers function to work properly.
    Also, I read through that link whiteflags, good stuff! Those atoi/atol/etc functions look perfect for a lot of what I'm doing. I don't think I needed them for the above two functions though, correct me if I'm wrong.

    So, here is the read_numbers function:

    Code:
    size_t read_numbers(int numbarr[])
    {
         int numint, i=0, r=0;
         rewind(fptr);
         while((numint = fgetc(fptr)) != EOF)
         {     
              i++;
         }
         r=i;
         i=0;
         rewind(fptr);
         while((numint = fscanf(fptr, "%d")) != EOF && i>=0 && i<=r)
         {
               numbarr[i]=numint;
               i++;          
         }
         return(numbarr[r]);         
    }

    I believe that that is functioning correctly, although I'm not entirely sure about the return(numbarr[r]); bit.

    Here is the print_numbers function:

    Code:
    void print_numbers()     
    {
         printf("Values contained within TXT File:\n\n");
         int i=0, r, numbarr[r];
         i=0;
         numbarr[r]=read_numbers(numbarr[r]);
         for(i=0; i=r; i++)
         {
               putchar(numbarr[i]);        
         }
         printf("\n\n");             
    }
    I get the warning message: [Warning] passing arg 1 of `read_numbers' makes pointer from integer without a cast

    When I compile it, then it crashes when the function is run.
    I come across that message quite a lot, and can't actually find a very good explanation of it on the internet; I'm guessing that I haven't got my pointers sorted out right?

    Cheers,
    Will

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,438
    Wow. I'm speechless. Your code shows so many misunderstandings of how C works that you could have easily reformatted your hard drive by running your program under some older operating systems. You can be thankful that modern operating systems are robust, so they protect your system from your programming errors.

    In your read_numbers() function, what is the purpose of the first loop? It appears to be that you are counting the characters in the file, and then using that number of characters as an upper limit on the number of integers being read in using scanf(). That strikes me as completely pointless: fscanf(), when using the %d modifier, will not read one character at a time - it will either read nothing and report an error (if data being read from the file cannot be interpreted as an int) or will read multiple (one or more) characters and interpret them as an integral value.

    You are "not entirely sure about the return numbar[r]; bit". If you are intending it to return the number of integers read from the file, then you are using completely the wrong approach.

    Your print_numbers() function has several problems. The first is the line
    Code:
        int i=0, r, numbarr[r];
    which defines numbarr as an array of r elements, where r is an uninitialised variable, so accessing its value gives undefined behaviour. The value of r is never changed in the function. Note that, in C, arrays do not magically resize themselves. Even if your code did change r to some valid value, the array numbarr will not be magically resized.

    The reason for the warning is that numbarr[r] is (ignoring the fact that r is uninitialised) an integral value. So your code is passing an integer to a function that expects to be supplied with a pointer or an array (as an array, when passed to a function, becomes a pointer). Either way, an array of int (or a pointer to int) is something different from an int.

    I suspect that you are somehow expecting that read_numbers() will be able to resize the array passed to it. Again, you are misinterpreting how arrays work. read_numbers() will not resize the array by reading elements into it, nor will it resize the array by changing the value of r.

    The loop inside print_numbers is also invalid. With
    Code:
        for (i = 0; i = r; i++)
    is not comparing i with r. Comparison for equality involves two equals signs, not one.

    Your usage of fscanf() in read_numbers() is also flawed .... EOF is not the only way that fscanf() reports an error. And putchar(numbarr[i]) in the loop within print_numbers() is not likely to output the values that you expect it to.
    Right 98% of the time, and don't care about the other 3%.

  13. #13
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    Yeesh.
    Your right I don't have a good understanding of C, I only started taking my programming course sriously last Wednesday. So the past 4 days have been trying to desperately catch up. I would explain why I didn't take it seriously but that is another story that is personal and irrelevant.
    But I am trying, I'm trying pretty damn hard in fact!

    The first loop in read_numbers() was trying to count the numbers in the file, I honestly couldn't think of a better way of doing it.
    So fscanf with the EOF statement will do the job fine itself?

    numbarr[r] was meant to be an array of size r, I made a mistake their initialising it with int, as it's dealing with only integer values I guess that "double numbarr[r]" would be more suitable?
    The return(numbar[r]) command was intended as returning the entire array, including it's size (r). That was the point of the value r, that it would define the size of the array; I just didn't know when and where to put it to be honest. As well as the fact that I wasn't sure if I could return both the array and it's size from read_numbers().
    And the if statement condition, that was a mistake, my bad.
    For the application of fscanf() that I am using here, is their a more suitable error checking command(s) that I could put in?
    Lastly, could you explain why putchar(numbarr[i]) won't function correctly? My understanding was that it would print a single character on the screen, from the array, onscreen? Would printf("%d", numbarr[i]) be more suitable?

    I know that's a lot of questions, and feel free not to answer them all, you've pointed me in the right direction so I'm going to get on the reading now.
    And yeah, I'm very grateful that my HD is not formatted!!!
    Thanks for the help.

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,438
    Quote Originally Posted by Williham View Post
    The first loop in read_numbers() was trying to count the numbers in the file, I honestly couldn't think of a better way of doing it.
    So fscanf with the EOF statement will do the job fine itself?
    The number of formatted values in a file (eg read using fscanf's %d format) will ALWAYS be less than the number of characters in the file. Think about it. So fscanf() can do the work. However, note that returning EOF is not the only way that fscanf() reports an error.

    Quote Originally Posted by Williham View Post
    numbarr[r] was meant to be an array of size r, I made a mistake their initialising it with int, as it's dealing with only integer values I guess that "double numbarr[r]" would be more suitable?
    The fact you even did it that way is broken.

    Defining "double numbarr[r]" is bad, even if r has been initialised to a (positive) value. In your code, r is uninitialised, so accessing its value can (theoretically at least) cause a program crash all on its own. The definition also does not somehow introduce magic so, if you set r to be 10, that numbarr will not be resized to hold ten elements.

    Quote Originally Posted by Williham View Post
    The return(numbar[r]) command was intended as returning the entire array, including it's size (r).
    All it does is return the value of numbar[r]. So if r is ten, the value returned will be numbarr[10] (assuming that numbarr has 11 or more elements).

    Quote Originally Posted by Williham View Post
    That was the point of the value r, that it would define the size of the array; I just didn't know when and where to put it to be honest. As well as the fact that I wasn't sure if I could return both the array and it's size from read_numbers().
    You're assuming that arrays can be passed around with their size. That is not true in C.

    An array is passed between functions as a pointer. A pointer does not contain information about how many values (eg an array) it points at. The size needs to be passed completely separately. Your trick does not magically return both the array and information about the size of the array.

    You're also forgetting that the variables r in your functions are local to the functions they are defined in. The r inside read_numbers() has no relationship to the r inside print_numbers(). They are distinct variables, each local to their own function. They are stored in different locations in memory, so changing one does not change the other.

    Quote Originally Posted by Williham View Post
    Lastly, could you explain why putchar(numbarr[i]) won't function correctly? My understanding was that it would print a single character on the screen, from the array, onscreen? Would printf("%d", numbarr[i]) be more suitable?
    putchar() outputs a single value. So putchar(13) will output a carriage-return character (assuming an ASCII character set). It will not print the text "13".

    Since you are reading values using scanf(), and want to output them in a similar manner, fprintf() is possibly a better option.
    Right 98% of the time, and don't care about the other 3%.

  15. #15
    Registered User
    Join Date
    Jun 2012
    Posts
    17
    K, this is my latest attempt at print_numbers:
    Code:
    void print_numbers()     
    {
         printf("Values contained within TXT File:\n\n");
         int numint;
         rewind(fptr);
         while((numint = fscanf(fptr, "%d")) != EOF)
         {
               fprintf(fptr, "%d", numint);  
         }
         printf("\n\n");             
    }
    I get an error stating that fptr is the wrong type argument to increment, which really confuses me as this is exactly how the book I'm using ("The C Programming Language" by Brian W.Kernighan & Dennis M Richie) states how to do it!

    My thinking was that with fprintf, after looking at how it works, I don't even need the read_numbers function to do print the values.

    Also, still using EOF as I haven't looked into alternatives yet and it seems to work OK.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Finding an array of unique values within a 2D array
    By saadashfaq in forum C Programming
    Replies: 6
    Last Post: 11-13-2011, 11:02 PM
  2. Replies: 1
    Last Post: 04-08-2011, 11:22 AM
  3. Int Array - Stop taking values at [zero]
    By bunko in forum C Programming
    Replies: 3
    Last Post: 12-03-2008, 11:54 PM
  4. Counting Numbers in Array, not counting last number!
    By metaljester in forum C++ Programming
    Replies: 11
    Last Post: 10-18-2006, 11:25 AM
  5. sizeof(array) returns differnt values for same array?
    By Diamonds in forum C++ Programming
    Replies: 6
    Last Post: 02-02-2003, 03:27 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21