Hi, I have a task to copy a .txt files content (alphabetically sorted) to binary file (one string at each line). Then user inputs name and I've to make a Binary Search function to check if the name is on that binary file or not.
I'm stuck at binary search function as it's .bin file it's hard to wrap my head around it. Program says that name is not on the file, even tho it is.
and
and_eq
asmauto
bitand
bitor
boolbreakcasecatchcharclassconstconst_castcontinuedefaultdeletedodoubledynamic_castelseenumexplicitexportexternfalsefloatforfriendgotoifinlineintlongmutablenamespacenew
not
not_eq
operator
or
or_eq
privateprotectedpublicregisterreinterpret_castreturnshortsignedsizeofstaticstatic_caststructswitchtemplatethisthrowtruetrytypedeftypeidtypenameunionunsignedusingvirtualvoidvolatilewchar_twhile
xor
xor_eq
It seems some words have trailing spaces so they can't be found. Not sure if they come from copy and paste here. Might be a good idea to remove them before you write the word to the binary file.
@Thomas1965 I actually took a look and understood, that this finding algorithm is nothing like 'BinarySearch' algorithm should be. That's not my task. I tried to modify and got till here. Same results (doesn't show that word exists, even tho it does)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
void BinarySearch(const string& filename, string SearchVal, int recordCount)
{
int pos;
constunsignedint RECORD_SIZE = 30; // was BUFFER_SIZE
char buffer[RECORD_SIZE] = {0}; // zero init buffer
int lowerLimit = 0;
int upperLimit = recordCount; //recordCount is 73 (counted prev)
while (lowerLimit <= upperLimit)
{
pos = (lowerLimit + upperLimit) / 2;
if (buffer == SearchVal) cout << "Got it!" << endl;
elseif (buffer < SearchVal)
lowerLimit = pos + 1;
elseif(buffer > SearchVal)
upperLimit = pos - 1;
}
}
std::string GetRecord(std::ifstream& inFile, int pos)
{
char buffer[RECORD_SIZE];
// clear possible flags like EOF, before moving the read position
inFile.clear();
// set the file read position to the requested record position
inFile.seekg(pos * RECORD_SIZE, std::ios::beg);
inFile.read(buffer, RECORD_SIZE);
// note: automatic conversion from char[] to std::string
return buffer;
}
void BinarySearch(const string& filename, string SearchVal)
{
ifstream file (filename.c_str(), ios::binary);
int pos = 0;
int lowerLimit = 0;
int recordCount = 73; // Calculated before[I'll change this part, when I get this function working]
// At this point, there's exactly 73 records in .bin file
char buffer[RECORD_SIZE] = {0}; // zero init buffer (while loop will overwrite with record values)
int upperLimit = recordCount;
while ( (lowerLimit < upperLimit) && (buffer != SearchVal)) // Searching as long as it didn't find it
{
pos = (lowerLimit + upperLimit) / 2;
std::string buffer = GetRecord(file, pos);
if (buffer == SearchVal){ cout << "Got it!" << endl; }
elseif (SearchVal > buffer) lowerLimit = pos + 1;
elseif (SearchVal < buffer) upperLimit = pos;
}
}
It works for same words like xor_eq but not for new. I guess you still have the problem with the trailing spaces. I also would change the BinarySearch so that it returns the position of the record or -1 if it doesn't find it. Also the condition in the while loop should be (lowerLimit <= upperLimit) see https://en.wikipedia.org/wiki/Binary_search_algorithm#Procedure
You are also redefining buffer inside the loop as a string. You probably should just define buffer as a string before the loop instead of using the C-string.
Since all of your values have only one word you could use the extraction operator>> in your create binary file function to eliminate any problems with trailing spaces.
You should always check that your file open operations actually succeed.
jlb and thomas, I changed while statement. When I open .bin file now, I still have like 8 spaces between every word, but exactly 8 so it's fixed. And, binary search now just crashes (nothing happens until I press 'X') Any ideas why?