Hello derekwtp-ga,
The 'fread()' function, in the <stdio.h> library,
is well documented. Try googling for 'fread' or
'fread example'. Two that I like are:
http://developer.novell.com/ndk/doc/clib/index.html?page=/ndk/doc/clib/sngl_enu/data/sdk1077.html
- has a nice, short example
http://www.qnx.com/developer/docs/momentics_nc_docs/neutrino/audio/wavec.html
- much longer, but gives you a complete program.
fread takes four arguments:
- a data pointer where the new data from the
file will be stored. you need a pointer to
a float.
- the size of each data value to read. here you
want a size of a float.
- the number of items (floats for you) to try to read.
- pointer to the FILE. you populate the pointer
using fopen().
The following code roughs out what you need. The
main loop reads in one floating point value at a time.
#include <stdio.h>
main()
{
float sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
float new_value;
int result;
FILE *datafile;
char *filename;
/* ADD CODE TO SET THE filename VARIABLE */
/* open the file */
datafile = fopen(filename, "r");
/* this is the main loop. */
result = 1;
while (result) {
/* fread will return 0 on error or end of file. */
result = fread(&new_value, sizeof(new_value), 1, datafile);
/* update the statistics with the new value in new_value */
if (result == 1) {
total_values++;
sum_intensities += new_value;
if (new_value > 0) {
total_nonzero_values++;
}
}
}
/* we read in the entire file and have the statistics */
/* in total_values, total_nonzero_values and sum_intensities */
}
Hopefully that is sufficient to complete your assignment.
dogbite-ga |
Request for Answer Clarification by
derekwtp-ga
on
19 Apr 2003 18:31 PDT
my output looks like this
[root@localhost ten]# ./a.out test.001
avg_values 0.000000
avg_nonzero 0.000000
[root@localhost ten]# ./a.out test.002
avg_values 0.000000
avg_nonzero 0.000000
[root@localhost ten]# ./a.out sunset1.jpg
avg_values 0.000000
avg_nonzero 0.000000
I don't know why im not able to print the output.
#include <stdio.h>
main(int argc, char *argv[])
{
float sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
int avg_values = 0;
int avg_nonzero = 0;
float new_value;
int result;
FILE *datafile;
char *filename;
/* SET THE filename VARIABLE */
filename=(argv[1]);
/* open the file */
datafile = fopen(filename, "r");
/* this is the loop. */
result = 1;
while (result) {
/* fread will return 0 on error or end of file. */
result = fread(&new_value, sizeof(new_value), 1, datafile);
/* update the statistics with the new value in new_value */
if (result == 1) {
total_values++;
sum_intensities += new_value;
if (new_value > 0) {
total_nonzero_values++;
}
}
}
avg_values= sum_intensities / total_values;
avg_nonzero= sum_intensities / total_nonzero_values;
printf ("avg_values %f\n",avg_values);
printf ("avg_nonzero %f\n",avg_nonzero);
}
|
Clarification of Answer by
dogbite-ga
on
20 Apr 2003 15:49 PDT
Hi derekwtp-ga,
Sorry for not getting back to you more quickly.
You should change the avg_values and avg_nonzero
variable declarations from ints to doubles. I
would also change sum_intensities to a double to
guard against overflow in the summation.
So you want:
double sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
double avg_values = 0;
double avg_nonzero = 0;
Please let me know if that helps you.
dogbite-ga
|
Request for Answer Clarification by
derekwtp-ga
on
21 Apr 2003 19:29 PDT
Sorry I took so long i been trying to decipher what my instructor
means. Anyhow, he doesnt like the while loop:
first, the whole point of loading data with an fread() is that
you don't have to convert it from ascii on disk to binary in
memory while the program is running. So, you don't have to read
the data one at a time. You read the entire file (array) with
one singe fread(). So get rid of the while loop.
saying:
if you are reading 16*16 floats with the fread() then the
loop that computes the averages has to execute 16*16 times.
So, you know this ahead of time.
As for which loop, the only difference is that there is less
overhead for the for loop. If you know ahead of time that
it has to execute 256 times, then you can use a for loop,
and you don't have to worry about incramenting a counter inside
the loop.
Using a while loop in this case will make the program
slower and less efficient, because the assembly code generated
for a while loop is uglier and slower. In our work here it
certainly won't be noticable, but in a bigger program with
more data, it would make a difference. Also, the for loop
is easier code to follow... all the guts are right there for
you. And you can use the loop index for the array index.
It works out nice.
I have changed my code to a for loop and it doesnt work. I dont know
how to get it to work while getting the counters to increment.
any help and explanation would be great
|
Clarification of Answer by
dogbite-ga
on
21 Apr 2003 19:44 PDT
Hi derekwtp-ga,
Okay, that's fine. I made only a few small
changes, as follows. I do not have the data
files that you do, so I cannot be sure that
it works. Here is the code though:
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
double sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
double avg_values = 0;
double avg_nonzero = 0;
float new_value;
int result;
FILE *datafile;
char *filename;
int img_rows;
int i;
/* SET THE filename VARIABLE */
filename=(argv[1]);
img_rows=(atoi(argv[2]));
/* open the file */
datafile = fopen(filename, "r");
/* this is the loop. */
result = 1;
for (i = 0; i < img_rows; i++) {
/* fread will return 0 on error or end of file. */
result = fread(&new_value, sizeof(new_value), img_rows, datafile);
/* update the statistics with the new value in new_value */
if (result == img_rows) {
total_values++;
sum_intensities += new_value;
if (new_value > 0) {
total_nonzero_values++;
}
}
else {
printf("invalid file format (result = '%d')\n", result);
exit(0);
}
}
avg_values= sum_intensities / total_values;
avg_nonzero= sum_intensities / total_nonzero_values;
printf ("avg_values %f\n",avg_values);
printf ("avg_nonzero %f\n",avg_nonzero);
}
dogbite-ga
|
Request for Answer Clarification by
derekwtp-ga
on
23 Apr 2003 15:23 PDT
dogbite,
I think what he is saying is that the fread() doesnt need to be in a
loop. In order to make that happen the new_value has to be a array.
Now in order to make this work format wise I get an error ten.c:65:
invalid operands to binary +
for sum_intensities += new_value; when I change this to a array. Also,
i couldnt get yours to compile and work right. You could use any image
file I found out. The notes abose said the input number is supposed to
be square.. Which i did but now i think my program still bites and I
dont know why. I am not getting values in my print statement ..instead
i am getting (without the array and w/ the fread() still in the loop)
[root@win186821wks ten]# ./a.out test.001 16
avg_values 0.000000
avg_nonzero 0.000000
Segmentation fault
/***************************************************************************
ten.c - description
-------------------
begin : Sat Apr 19 2003
copyright : (C) 2003 by Derek S. Winchester
email : dswinchester@winchester1.com
***************************************************************************/
/***************************************************************************
*
*
* This program is free software; you can redistribute it and/or
modify *
* it under the terms of the GNU General Public License as published
by *
* the Free Software Foundation; either version 2 of the License, or
*
* (at your option) any later version.
*
*
*
***************************************************************************/
\
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
double sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
double avg_values = 0;
double avg_nonzero = 0;
float new_value[400];
int result;
FILE *datafile;
char *filename;
int img_rows;
int i;
int size;
/* SET THE filename VARIABLE */
filename=(argv[1]);
img_rows=(atoi(argv[2]));
size= img_rows*img_rows;
/* open the file */
datafile = fopen(filename, "r");
/* this is the loop. */
result = 1;
for (i = 0; i < size; i++) {
/* fread will return 0 on error or end of file. */
result = fread(&new_value, sizeof(new_value), size, datafile);
/* update the statistics with the new value in new_value */
if (result == size) {
total_values++;
sum_intensities += new_value;
if (new_value > 0) {
total_nonzero_values++;
}
}
/*else {
printf("invalid file format (result = '%d')\n", result);
exit(0);
} */
}
avg_values= sum_intensities / total_values;
avg_nonzero= sum_intensities / total_nonzero_values;
printf ("avg_values %f\n",avg_values);
printf ("avg_nonzero %f\n",avg_nonzero);
}
pleaes help..thanks
|
Clarification of Answer by
dogbite-ga
on
23 Apr 2003 15:33 PDT
Okay, let me take a look.
Is there any way you make one
of your image files web-accessible?
Can you link one from a webpage?
Then I could try it for sure.
Also, this "not using fread() in a
loop" is a bit beyond the origional
question's scope. I understand the
wants of professors though. When we
get this all wrapped up, any tips would
be greatly appreciated! :-)
dogbite-ga
|
Request for Answer Clarification by
derekwtp-ga
on
23 Apr 2003 16:17 PDT
Okay dude I got it running. Can you help me w/ my parser code. I have
to add this ini the program..here is my program and the parser example
will follow..thanks in advance dog man.: )
/***************************************************************************
ten.c - description
-------------------
begin : Sat Apr 19 2003
copyright : (C) 2003 by Derek S. Winchester
email : dswinchester@winchester1.com
***************************************************************************/
/***************************************************************************
*
*
* This program is free software; you can redistribute it and/or
modify *
* it under the terms of the GNU General Public License as published
by *
* the Free Software Foundation; either version 2 of the License, or
*
* (at your option) any later version.
*
*
*
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
double sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
double avg_values = 0;
double avg_nonzero = 0;
float new_value[400];
int result;
FILE *datafile;
char *filename;
int img_rows;
int i;
int size;
/* SET THE filename VARIABLE */
filename=(argv[1]);
img_rows=(atoi(argv[2]));
size = (img_rows*img_rows);
/* open the file */
datafile = fopen(filename, "r");
/* this is the loop. */
result = 1;
/* fread will return 0 on error or end of file. */
result = fread(&new_value, sizeof(float), size, datafile);
for (i = 0; i < size; i++) {
/* update the statistics with the new value in new_value */
if (result == size) {
total_values++;
sum_intensities += new_value[i];
if (new_value[i] > 0) {
total_nonzero_values++;
}
}
else {
printf("invalid file format (result = '%d')\n", result);
exit(0);
}
}
avg_values= sum_intensities / total_values;
avg_nonzero= sum_intensities / total_nonzero_values;
printf ("avg_values %e\n",avg_values);
printf ("avg_nonzero %e\n",avg_nonzero);
printf ("total_values %e\n",total_values);
printf ("total_nonzero_values %e\n",total_nonzero_values);
}
[root@win186821wks c]# more parser.c
main(int argc, char** argv)
{
int age,month,maxargs,i;
char name[80];
/*(NOTE: this may look overkill but please notice how easy
it will be to add another command line option, or to
add another 50 options! If there is something
you don't undestand, please mail me questions.
I added the "main" stuff above and the printf()
at the end, just so you can compile and run the
program to see how it works.
*/
/*
current command line arguments:
-n name User's first name ("Sean" is default)
-m month integer month (default is "1" for January)
-a age integer age (default is "39" :) )
*/
maxargs = 7;
/* check for too many command line arguments */
if (argc > maxargs) {
printf("Usage: %s [-n name -m month -a age ]\n",argv[0]);
exit(1);
}
/* set default values */
strcpy(name,"Sean");
month = 1;
age = 39;
for (i=1;i<argc;i+=2) {
/* check for valid flags (first char should be '-' for flags) */
if (argv[i][0]!='-') {
printf("bad option character...should be \"-\"\n");
exit(2);
}
/* check for valid flag value and take appropriate action */
switch (argv[i][1]) {
case 'n': strcpy(name,argv[i+1]);
break;
case 'm': month = atoi(argv[i+1]);
break;
case 'a': age = atoi(argv[i+1]);
break;
default: printf("bad option...should be \"n\" or \"m\" or
\"a\"\n");
exit(3);
break;
}
}
printf("age = %d, month = %d, name = %s\n",age,month,name);
}
|
Clarification of Answer by
dogbite-ga
on
23 Apr 2003 16:18 PDT
Hey derekwtp-ga,
Here is a new version of the program,
sans loop. Another change is that I
added a threshold test for the non-zero
value. floats are rarely *zero* on the
dot, and it seemed that very-near-zero
values were being incorrectly counted as
non-zero.
I tried this on a few image files, and
it worked for me. Let me know how it
works for you.
#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[])
{
double sum_intensities = 0;
int total_values = 0;
int total_nonzero_values = 0;
double avg_values = 0;
double avg_nonzero = 0;
float *new_value;
int result;
FILE *datafile;
char *filename;
int img_rows;
int i;
int size;
/* SET THE filename VARIABLE and number of image rows */
filename=(argv[1]);
img_rows=(atoi(argv[2]));
size= img_rows*img_rows;
/* malloc our array of floats */
new_value = malloc(size * sizeof(float));
/* open the file */
datafile = fopen(filename, "r");
/* this is the loop. */
result = 1;
result = fread(new_value, sizeof(float), size, datafile);
if (result == size) {
total_values = size;
for (i = 0; i < size; i++) {
sum_intensities += new_value[i];
// if (new_value[i] != 0) {
if ((new_value[i] < 0.0000001) &&
(new_value[i] > -0.0000001)) {
total_nonzero_values++;
}
}
}
else {
printf("invalid file format (result = '%d')\n", result);
exit(0);
}
// printf("sum:\t\t%f\n", sum_intensities);
// printf("total: %d \nnonzero: %d\n", total_values, total_nonzero_values);
avg_values= sum_intensities / total_values;
avg_nonzero= sum_intensities / total_nonzero_values;
printf ("avg_values\t %f\n",avg_values);
printf ("avg_nonzero\t %f\n",avg_nonzero);
/* free the memory we malloced */
free(new_value);
}
dogbite-ga
|
Request for Answer Clarification by
derekwtp-ga
on
23 Apr 2003 16:34 PDT
thanks dog..im hoping you saw my last input before yours
|
Clarification of Answer by
dogbite-ga
on
23 Apr 2003 16:48 PDT
hey derekwtp,
can you be more specific on what
you want? what command line options
is it supposed to accept?
dogbite-ga
|
Request for Answer Clarification by
derekwtp-ga
on
23 Apr 2003 18:48 PDT
like if I do a ./a.out img.file 16 or if I do a ./a.out 16 img.file
..both would be accepted .. or if I do just a ./a.out it would take a
default like test.001 file. That is very tough to do i think
|
Clarification of Answer by
dogbite-ga
on
23 Apr 2003 20:23 PDT
Hey derekwtp-ga,
I'd be happy to add some basic command-line
option handling for you. Could you please
post it as another question though? I feel
it is too far beyond the scope of this question.
Just put "For dogbite-ga ONLY" in the title,
and I'll grab it.
dogbite-ga
|