#include <windows.h>
#include <ntdll.h>
#include <commdlg.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"Comdlg32.lib"

int __cdecl Main(int argc,char *argv[])
{
//vars for file path
wchar_t wFullPath[MAX_PATH] = {0};
wchar_t wFileName[MAX_PATH] = {0};
wchar_t wFileExt[MAX_PATH] = {0};
//var for storage of text..I know I should do a chunk at a time
//approach for this..but gimme a brake..this was hard enough.. :}
char ReadBuffer[MAX_PATH] = {0};
//structure for GetOpenFileName()
OPENFILENAME ofn = {0};
//Handle to the selected file
HANDLE hFile = 0;
//var that stores the bytes read from the selected file
ULONG BytesRead = 0;
//string tokenize vars
char *StrBuf = 0;
char *InpBuf = 0;
//var that hold the number of inputs that come with interpretting this data structure
int NumInputs = 0;
//interators and storage indexers
int i = 0,x = 0;
//vars for data testing storage and results
float fData,tData = 0;
float fResult = 0;
float Inputs[100] = {0};
//program run modifyier
bool fRun = 0;
wcout<<L"This is the solution for finding the average of a random set of values."<<endl;
wcout<<L"Please select input file"<<endl;
//set the storage to all 0's
memset(&Inputs,0,sizeof(float)*100);
//setup the structure for GetOpenFileName
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = NULL;
ofn.lpstrFile = wFullPath;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof( wFullPath );
ofn.lpstrFilter = L"Text\0*.TXT\0";
ofn.nFilterIndex =1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir=NULL;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;
//http://msdn.microsoft.com/en-us/library/ms646927(VS.85).aspx
GetOpenFileName(&ofn);
//http://msdn.microsoft.com/en-us/library/e737s6tf.aspx
_wsplitpath(wFullPath,0,0,wFileName,wFileExt);
wcout<<wFileName<<wFileExt<<L" selected"<<endl;
wcout<<L"Beginning processing of file."<<endl;
wcout<<L"Now validating file structure."<<endl;
//http://msdn.microsoft.com/en-us/library/bb540534(VS.85).aspx
//Open the selected file
hFile = CreateFile(wFullPath,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile == INVALID_HANDLE_VALUE)
{
wcout<<L"Failed to open file.."<<endl;
return 1;
}
//Read the file into ReadBuffer
if(ReadFile(hFile,ReadBuffer,MAX_PATH,&BytesRead,0) == FALSE)
{
wcout<<L"Failed to read file.."<<endl;
CloseHandle(hFile);
return 2;
}
//test if we read anything
if(BytesRead > 0)
{
//http://msdn.microsoft.com/en-us/library/zkx076cy(VS.80).aspx
if(!sscanf(ReadBuffer,"%d",&NumInputs))
{
wcout<<L"Failed Validation"<<endl;
return 3;
}
if(NumInputs > 98)
{
wcout<<L"Inputs to high"<<endl;
return 4;
}
wcout<<L"Successful Validation of File Structure."<<endl;
wcout<<L"Number of Inputs:"<<NumInputs<<endl;
wcout<<L"Begin parsing of file data."<<endl;
//http://msdn.microsoft.com/en-us/library/z9da80kz(VS.80).aspx
//get past the first carriage return and newline separators.
StrBuf = strstr(ReadBuffer,"\r\n"

;
//http://msdn.microsoft.com/en-us/library/2c8d19sb(VS.71).aspx
//tokenize the string to separate out the data
InpBuf = strtok(StrBuf,"\r\n"

;
Digest:
//make sure result = 0 so no tainting occurs..(bug #3)
fResult = 0;
for(i = 0;i<NumInputs;i++)
{
if(!fRun)
{
//change the ascii to floats(really doubles..)
Inputs[I] = atof(InpBuf);
}
//add up the result and check for -1 that signifies faulty data.
fResult += Inputs[I] != -1 ? Inputs[I] : 0;
if(!fRun)
{
wcout<<L"Data["<<i<<L"]"<<L" = "<<Inputs[I]<<endl;
//get next tokenized string part
InpBuf = strtok(NULL,"\r\n"

;
}
}
if(!fRun)
{
//caclulate the prelimanary result added
//up result divided by the number of inputs
fResult = fResult/NumInputs;
wcout<<L"Prelimanary average result: "<<fResult<<endl;
wcout<<L"Scanning array for faulty data"<<endl;
i = 0;
//x equals NumInputs + 1 because we want 2 unused areas
x = NumInputs + 1;
do
{
//check storage for current farthest value
if(Inputs[x - 1] == 0)
{
//calculate the proper subtraction sequence
fData = Inputs[I] > fResult ? Inputs[I] - fResult : fResult - Inputs[I];
}
else
{
//set fData to current farthest value..(unneeded..but w/e)
fData = Inputs[x - 1];
}
//increment i to calculate next subtraction sequence
i++;
tData = Inputs[I] > fResult ? Inputs[I] - fResult : fResult - Inputs[I];
//if current fData > tData and i == 1 the index of fData = i - 1 or 0..
if(fData > tData && i == 1)
{
Inputs[x] = i - 1;
//store the fartherest data in NumInputs or x - 1..for all those following..
Inputs[x - 1] = fData;
}
//blah blah blah see above adjust as seen below ;p
if(tData > fData)
{
Inputs[x] = i;
Inputs[x - 1] = tData;
}
}while(i < NumInputs -1);
i = Inputs[x];
wcout<<L"Faulty data: "<<Inputs[I]<<L" Index:"<<i<<endl;
wcout<<L"Modifying faulty data."<<endl;
Inputs[I] = -1;
fRun++;
goto Digest;
}
else
{
//calculate the final result,
//Result = sum of array divided by NumInputs - 1
//to account for the removed data..
fResult = fResult/(NumInputs - 1);
wcout<<L"Final average result: "<<fResult<<endl;
}
}
wcout<<L"Finished"<<endl;
CloseHandle(hFile);
return 0;
}