I have this function:
void ToUpper(char * S)
{
while (*S!=0)
{
*S=(*S >= 'a' && *S <= 'z')?(*S-'a'+'A'):*S;
S++;
}
}
What does it mean for *S != 0, should it be null instead?
I have this function:
void ToUpper(char * S)
{
while (*S!=0)
{
*S=(*S >= 'a' && *S <= 'z')?(*S-'a'+'A'):*S;
S++;
}
}
What does it mean for *S != 0, should it be null instead?
That is checking for the end of the string which is a character which has the value of zero. It is not connected to NULL pointers in any way.
I would write it *S != '\0'
as I feel that is more idiomatic, but that is really just personal style preference. You are checking for the null character (ASCII NUL).
You might also consider checking S != 0
before any of that code as the pointer itself may be null, and you don't want to dereference a null pointer.
I like algorithms better than loops:
#include <algorithm>
#include <cstring>
#include <cctype>
void ToUpper(char* p)
{
std::transform(p, p + strlen(p), p, toupper);
}
This solution also works for character encodings where a to z aren't sequential.
Just for fun, here is an experiment that only does one iteration with algorithms:
#include <algorithm>
#include <cassert>
#include <cstring>
#include <cctype>
#include <iostream>
#include <iterator>
struct cstring_iterator : std::iterator<std::random_access_iterator_tag, char>
{
char* p;
cstring_iterator(char* p = 0) : p(p) {}
char& operator*()
{
return *p;
}
cstring_iterator& operator++()
{
++p;
return *this;
}
bool operator!=(cstring_iterator that) const
{
assert(p);
assert(!that.p);
return *p != '\0';
}
};
void ToUpper(char* p)
{
std::transform(cstring_iterator(p), cstring_iterator(),
cstring_iterator(p), toupper);
}
int main()
{
char test[] = "aloha";
ToUpper(test);
std::cout << test << std::endl;
}
NULL is a pointer while *S is the value stored at the pointer. Thankes to Dennis Ritchie, the digit 0 is acceotable as both.