Hey guys I'm back again with hopefully the last chapter in my C-string saga. What's really messed up is that my compare function WORKS, just not when I get input from a user. Check out my main below. The first block is what the program's supposed to do; get the strings from a user and do stuff with them. But when they enter the same string, it does not report them as equal. Even though it DOES in the next block PERFECTLY!
This is the type of stuff why I don't think I'm cut out to be a full-time programmer
EDIT: Also, just like with my prior C-string posts, my instructor won't let us change the function headers given from the prototypes. It's like working in steal cage here
// Author: Matt
// File: mjccstring.cpp
// Operating System: Linux
// Compiler: g++
// Written: 2/2013
// Assigned: 2/7/2013
// Due: 2/15/2013
// Purpose: This program will take two strings as input from the user, and perform various C-String related tasks with them
#include <iostream>
//prototypes
int mjcStrLen(constchar * const);
int mjcStrCmp(constchar [], constchar []);
//initializes variables and calls the other functions
int main()
{
char cstring1[256];
char cstring2[256];
std::cout << "Please enter the text for the 1st string. Press enter when done: ";
std::cin.getline (cstring1, 256);
std::cout << "Please enter the text for the 2nd string. Press enter when done: ";
std::cin.getline (cstring2, 256);
std::cout << "String \"" << cstring1 << "\" is " << mjcStrLen(cstring1) << " characters long." << std::endl;
std::cout << "String \"" << cstring2 << "\" is " << mjcStrLen(cstring2) << " characters long." << std::endl;
std::cout << "Return vaule of mjcStrCmp is: " << mjcStrCmp(cstring1, cstring2) << std::endl;
if(mjcStrCmp(cstring1, cstring2) == 0)
std::cout << "String \"" << cstring1 << "\" is equal to \"" << cstring2 << "\"." << std::endl;
else
std::cout << "String \"" << cstring1 << "\" is not equal to \"" << cstring2 << "\"." << std::endl;
std::cout << std::endl;
std::cout << "mjcStrCmp Test: Created two new strings which should be equal" << std::endl;
char cstring3[256] = "Testing";
char cstring4[256] = "Testing";
std::cout << "Return vaule of mjcStrCmp is: " << mjcStrCmp(cstring3, cstring4) << std::endl;
if(mjcStrCmp(cstring3, cstring4) == 0)
std::cout << "String \"" << cstring3 << "\" is equal to \"" << cstring4 << "\"." << std::endl;
else
std::cout << "String \"" << cstring3 << "\" is not equal to \"" << cstring4 << "\"." << std::endl;
return 0;
}
//uses a while loop to count the number of characters in a C-string
int mjcStrLen(constchar * const test_string)
{
int length = 0;
int index = 0;
while(*(test_string + index)) //will be true until it hits the null character
{
length++;
index++;
}
return length;
}
//compares ascii values of each character, returns 1 if larger, 0 if equal, or -1 if smaller
int mjcStrCmp(constchar test_string1[], constchar test_string2[])
{
int return_value = 0;
for(int index = 0; index < 256; index++)
{
if(test_string1[index] > test_string2[index])
{
return_value = 1;
index = 256; //will skip rest of string once it finds a different character
}
elseif(test_string1[index] < test_string2[index])
{
return_value = -1;
index = 256;
}
}
return return_value;
}
In function mjcStrCmp(), instead of checking for a fixed number of characters (256), the testing should end when the null terminator of either string is reached.
That doesn't look right.
The loop should end when either test_string1[index] == '\0'
or test_string2[index] == '\0'
though of course there are many ways to put that into code.
for(int index = 0; test_string1[index] || test_string2[index] || return_value == 0; index++)
That condition is wrong. The condition says
"while ((the character at index index of test_string1 is not 0) OR (the character at index index of test_string2 is not 0) OR (return_value is 0))"
The condition you want should say
"while ((return_value is 0) AND (the character at index index of test_string1 is not 0) AND (the character at index index of test_string2 is not 0))"
Remember, the condition should be true while it runs - it is NOT the condition to stop at.
Putting the check for end-of-string at the start of the loop doesn't completely make sense. If one string is longer than the other, say "dog" and "dogs", you still need to enter the loop to see which string is greater or lesser.
I'd prefer to test the condition at the end of each pass through the loop.
That looks very similar to a version that I came up with, but some differences
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
int mjcStrCmp(constchar one[], constchar two[])
{
int ix = -1;
do
{
ix++;
if (one[ix] > two[ix])
return 1;
if (one[ix] < two[ix])
return -1;
} while (one[ix] && two[ix]);
return 0;
}
Indeed, that probably would have been what I would have wrote, but unfortunately the instructor's really anal about certain things. Such as one exit/return statement for each function.
*sigh* Gonna be so glad when this semester's over, and it's still only February
Such as one exit/return statement for each function.
Heh, that's back from in C where objects aren't automagically destructed at the end of their scope and so you would have to copy de-initialization code before every return. In C++ you don't worry about that anymore.
At the end of your loop, idx is not out of either array's bounds. You can therefore remove the if statements from the loop and do the calculation in the return statement:
@L B Yeah he's a real old-school C guy. I can tell. Cool guy personally, just really challenging. Believe it or not I've had two prior C++ courses years ago, and taking this one makes me realize I must not have learned much from the others. It's sweetly agonizing if that makes any sense >_<