Just iterate through the text and swap characters:
int main ()
{
char text[] = "...Z.Z.Z...", temp;
int text_len = strlen (text), ii;
for (ii = text_len - 1; ii >= 0; ii--)
{
if (text[ii] == 'Z')
{
temp = text[ii+1];
text[ii+1] = text[ii];
text[ii] = temp;
}
}
printf ("%s\n", text);
return 0;
}
Produces:
[~]$ gcc zshift.c && ./a.out
....Z.Z.Z..
There's a lot of discussion in the comments about a possible off-by-1 error in the above code. However, simple testing / stepping through is enough to show that this is not the case.
zshift "Z." -> ".Z"
zshift ".Z" -> "."
zshift "Z" -> ""
I think the behavior of "dropping" trailing Zs when shifting off the end of the string is sensible. After all, if you shift the bits of an integer, bits that end up outside the bounds of the integer are dropped.
If another behavior is desired -- for example, shifting only within the string -- the change to the algorithm is minimal:
temp = text[ii+1];
if (temp == 0) continue;
text[ii+1] = text[ii];
text[ii] = temp;