Reputation: 713
I've written a c program which can read a text file with single column of data. All the data can be read into the program with the following codes:
#include <stdio.h>
#include <cstdlib>
main()
{
char temp[20];
float t;
int a = 0, x = 0; //a is no. of data greater than 180 and x is no of data
FILE *fpt;
fpt = fopen("case i.txt", "r");
fscanf(fpt, "%s", temp); // read and display the column header
printf("%s\n", temp);
while (fscanf(fpt, "%f", &t) == 1)
{
printf("%.2f\n", t);
++x; //count for number of data
if (t > 180) {
++a; //count for number of data > 180
}
if (x > 2 && a == 2) { //place where bug is expected to occur
printf("2 out of 3 in a row is greater than 180");
a=0; //reset a back to zero
x=0;
}
}
fclose(fpt);
system("pause");
}
The problem comes when I want to detect like 2 out of 3 data are beyond 180 degree Celsius. I tried some ideas like when (no. of data > 2) and (two data > 180) then generate an error message, but it will have bug as it may have two data > 180 but when 4 data are read, that means it become 2 out of 4, not 2 out of 3, is it possible to be programmed? Thank you in advance for every help.
The following is the sample data and output:
Upvotes: 0
Views: 99
Reputation: 58244
You'll need to keep a "sliding window" of 3 values indicating how many are over 180.
So one approach would be something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char temp[20];
float t;
const int min_over = 2;
const int max_window = 3;
const int max_value = 180;
char over[max_window]; // a 1 means over, 0 otherwise
int oi = 0;
int num_values = 0;
FILE *fpt;
fpt = fopen("case i.txt", "r");
fscanf(fpt, "%s", temp); // read and display the column header
printf("%s\n", temp);
memset(over, 0, max_window);
while (fscanf(fpt, "%f", &t) == 1)
{
int num_hit, i;
printf("%.2f\n", t);
// Calculate num_hit: how many over in a window of max_window
//
over[oi] = (t > max_value) ? 1 : 0;
if (++oi >= max_window)
oi = 0;
for ( num_hit = i = 0; i < max_window; i++ ) num_hit += over[i];
// Only check for min_over/max_window after at least
// max_window values read; Reset the check
//
if ((++num_values >= max_window) && (num_hit >= min_over))
{
printf("It happened!\n");
memset(over, 0, max_window);
num_values = 0;
}
}
fclose(fpt);
system("pause");
}
Since you want a ratio of 2/3, that corresponds to min_over / max_window
values.
I ran this on your commented data sample:
Temperature
190.00
190.00
170.00
It happened!
200.00
190.00
100.00
It happened!
100.00
190.00
190.00
It happened!
Upvotes: 1
Reputation: 49403
There are about a million billion different ways to do this, but you just need to keep track of how many samples exceed the threshold and then do whatever you want to do when you hit that mark.
Let's say, once you find your "2 out of 3" samples that exceed 180 you want to print the list and stop reading from the file:
FILE *fpt;
float t;
float samples[3] = {0}; // keep a record of 3 samples
int total = 0, i;
fpt = fopen("file1.txt", "r");
while (fscanf(fpt, "%f", &t) == 1) // read until there are no more samples
{
total = 0; // clear our counter
samples[2] = samples[1]; // toss out the old 3rd sample
samples[1] = samples[0]; // and shift them to make room for the
samples[0] = t; // one we just read
for(i = 0; i<3; i++)
if(samples[i] > 180) // if any are over 180
total++; // increment our counter
if(total == 2) { // if 2 of the 3 are over 180, we got 2 out of 3
printf("2 out of 3 samples are greater than 180!\n");
printf("1: %f\n2: %f\n3:%f\n", samples[2],samples[1],samples[0]);
break;
}
}
fclose(fpt);
It's not very efficient.. but should be pretty easy to understand.
Upvotes: 1