Well, the easy answer is; don't reinvent the wheel, use existing tools:
var numberOfWords =
sentence.Split(
' ',
StringSplitOptions.
RemoveEmptyEntries).Length;
But that would be cheating...
So, taking your code, there are a few things that need to be fixed:
First, don't make your method do too many things. There is no reason why a method counting words should know anything about how to output the result to any given user interface. Simply make a method that knows how to count words and returns the number of words:
public static int CountWords(string sentence) { ...}
Now you can reuse this method in any type of application; console, windows forms, WPF, etc.
Second, take corner or trivial cases out of the equation fast. Null sentences are either an error or have no words. Make a choice on how you want to process this scenario. If 0 words makes sense, you can solve a few cases in one strike:
if (string.IsNullOrWhiteSpace(sentence))
return 0;
Third, don't perform unnecessary conversions; converting chars to strings simply to perform an equality check with " "
is wasteful. Compare chars directly (' '
), or use the aptly named char.IsWhiteSpace
(+) method.
Fourth, your logic is flawed. Double spaces, leading spaces, etc. will all give you wrong results. The reason being that your condition on when to count a word is faulty. Encountering a whitespace doesn't necessarily mean a new word is on the way; another whitespace might be waiting, you’ve already encountered a white space in the previous iteration, the sentence might end, etc.
In order to make your logic work you need to keep track of what happened before, what’s happening now and what will happen next... if that sounds messy and over complicated, don’t worry, you are absolutely right.
A simpler way is to shift your logic just a little; let’s say we encounter a new word everytime we find a non whitespace(*) that is preceded by a whitespace. What happens after is irrelevant, so we’ve just made things a lot easier:
var counter = 0;
var words = 0;,
var previousIsWhiteSpace = false;
while (counter < sentence.Length)
{
if (char.IsWhiteSpace(sentence[counter]))
{
previousIsWhiteSpace = true;
}
else if (previousIsWhiteSpace)
{
words += 1;
previousIsWhiteSpace = false;
}
counter += 1;
}
Put it all together and you are done.
(+) this will actually flag more than a regular space as a valid whitespace; tab, new line, etc. will all return true.
(*) I’m ignoring scenarios involving punctuation marks, separators, etc.