0

**I can't use vectors, or any functions from the standard library with this program. Hence why I am writing it all myself.

Alright, this program is just about finished. All my user defined functions are working fine, except for the reverseCString function. When I run the program, and enter a string of "hello", I can select menu option "rev" to reverse the string. My main function then calls the reverseCString function, and uses the for loop in my main to print out my reversed c-string. The program works fine at this point, until the do-while loop continues..

After the rv function is called though, the program loops to continue to allow the user to modify their string, as it should. However, my c-string vanishes at this point. I can still operate on it if I use the other commands/funtions, but the c-string doesn't print to cout.

I don't understnad what is causing this, but I have isolated the problem down to the reverseCString function.

Here is my code so far:

#include<iostream>
#include<stdlib.h>
#include<cstring>
#include<string>
#include<math.h>

using namespace std;


void shiftLeft(char szString[], size_t shiftBy)
{
    const char *p = szString;//
    while (*p) ++p;//advance p to point to the the null terminator, found via personal research at http://stackoverflow.com/questions/12201815/what-difference-between-whilepp-while-p-and-whilep
    size_t len = p - szString;//len is set to the size of our c-string 

    if (len > 1 && (shiftBy %= len))
    {
        char *ends[] = { szString+shiftBy, szString+len, szString+(len - shiftBy) };//create a temporary array for storage
        for (size_t i = 0; i < 3; ++i)//use a for loop to flip the first three character
        {
            char *start = szString, *end = ends[i];
            while (start < --end)//now flip the rest of the characters
            {
                char ch = *start;
                *start++ = *end;
                *end = ch;
            }
        }
    }
}


void shiftRight (char szString[], int size, int shiftBy)
{
    if(shiftBy > size){
        shiftBy = shiftBy - size;
    }
    if(size == 1){
        //do nothing, exit function with no change made to myarray
    }
    else{
        char temp;
        //for loop to print the array with indexes moved up (to the right) --> by 2
        for (int i=0; i < size; i++)
        {//EXAMPLE shift by 3  for a c-string of 5
            temp = szString[size-shiftBy];//temp = myarray[2]
            szString[size-shiftBy] = szString[i];//myarray[2] = myarray[i]
            szString[i] = temp;//myarray[i] = temp(value previously at index 2)
        }

    }
}


void reverseCString(char szString[], const size_t& size){
    char temp;
    int i = 0;
    int j = size-1;

    //we can use a simple tep variable to flip everything
    while(i < j)
    {
        temp = szString[i];
        szString[i] = szString[j];
        szString[j] = temp;
        i++;
        j--;
    }
}

    int main(){

        string repeat = "";

        string userInputString;
            cout << "Please eneter your string: " << endl;
            //cin >> ws;
            getline(cin,userInputString);


            char * szString = new char [userInputString.length()+1];
            strcpy (szString, userInputString.c_str());



        do {


            cout << "Your c-string is: " << szString << endl;

            string commandString = "";
            cout << "Please enter a command: ";
            getline(cin,commandString);

            if (commandString[0] == 'L'){
                cout << "You have chosen to shift your string left by " << commandString[1] << " characters." << endl;
                const char * shiftLeftPtr = &commandString[1];
                //convert this value to an int for our function
                int shiftLeftBy = atoi(shiftLeftPtr);
                //run our shifleft function
                shiftLeft(szString,shiftLeftBy);
                //print the results
                cout << "Your c-string, shifted left by " << commandString[1] << endl;
                cout << szString;

            }

            if (commandString[0] == 'R'){
                cout << "You have chosen to shift your string right by " << commandString[1] << " characters." << endl;
                const char * shiftRightPtr = &commandString[1];
                //convert this value to an int for our function
                int shiftRightBy = atoi(shiftRightPtr);
                //run our shiftright function
                shiftRight(szString,userInputString.length(),shiftRightBy);
                //print the results
                cout << "Your c-string, shifted right by " << commandString[1] << endl;
                cout << szString;

            }

            if (commandString.compare("rev") == 0){
                cout << "You have chosen to reverse your string. " << endl;
                //run our reverseArray function
                reverseCString(szString,userInputString.length()+1);

                cout << "Your c-string, reversed: ";
                for(int i = 0; i < userInputString.length()+1; i++){
///////////////////////////right her seems to be my issue
                cout << szString[i];
                }

            }

            if (!(commandString[0] == 'R' || commandString[0] == 'L' || commandString.compare("rev") == 0)){
                cout << "You have entered an invalid selection." << endl;
            }

            cout << "\nEnter 'quit' to close the program, anything else to continue: ";
            getline(cin,repeat);

        }while(repeat.compare("quit") != 0);

        return 0;
    }
  • sorry, no standard library functions can be used to reverse the string. –  Nov 06 '14 at 04:27
  • Did you step through the logic of the code with an example string (either on paper or with a debugger) so see what it would do? – David Schwartz Nov 06 '14 at 04:34
  • You bet I did, I have done that several times. The function is working, my c-string is being reversed. The issue seems to be somewhere in my main, when the c-string magically disapears. –  Nov 06 '14 at 04:36
  • So if the string is "bar", what `size` do you think is passed to `reverseCString`? – David Schwartz Nov 06 '14 at 04:37
  • 4. 3 characters + null terminator. –  Nov 06 '14 at 04:37
  • GREAT GANDALFS BEARD! EUREKA! –  Nov 06 '14 at 04:39
  • I totally misunderstood that my size parameter really meant "total indexes" and not total elements. So I was indeed passing length+1 by mistake. –  Nov 06 '14 at 04:40

1 Answers1

2

Your length logic is broken. Say the string contains "bar\0". You do this:

            reverseCString(szString,userInputString.length()+1);

Now, length is 3, and you pass 4 to reverseCString. Then this happens:

void reverseCString(char szString[], const size_t& size){
    char temp;
    int i = 0;
    int j = size-1;

Now, i is 0 and j is 3. So you swap items 0 and 3. Well, what are the items?

0 = b
1 = a
2 = r
3 = \0

When you swap items 0 and 3, you create a string that starts with a terminator, "\0rab". Of course printing that out won't produce anything.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • It's a null terminated array of chars, a c-string. I apologize for not mentioning that. –  Nov 06 '14 at 04:34
  • @DracoM. The point is that you want to be reversing the chars that come before the null terminator (instead of including the terminator in the reversal) – M.M Nov 06 '14 at 04:37