Home > OS >  How to locate and remove these symbols from my reversed string
How to locate and remove these symbols from my reversed string

Time:11-21

This is an oddly specific problem but I need help because I am very confused. I am trying to use pointers to ask a user to input a string and the output will print the reverse. So far I have used a reverse function and applied the pointers. Here's what the code looks like right now:

#include <iostream>
using namespace std;

void reverse(char name[])
{
    char *p;
    p = name;

    while (*p != '\0')
    {
          p;
    }
    while (*p >= 0)
    {
        cout << *p;
        --p;
    }
}

int main()
{
    char name[100];

    cout << "Please enter a string: ";
    cin.getline(name, sizeof(name));

    cout << "The reverse of the string is: ";

    reverse(name);

    return 0;
}

When I run the program, it works but there is one problem. For example the inputted string is Stack Overflow, this is the result:

Please enter a string: Stack Overflow
The reverse of the string is:  wolfrevO kcatS    ►☺ ◄                   a 

As you can see there are these symbols that show up in the final output. I have tried locating where it comes from and I think it is because of the pointers because when I used an array for the function, it properly printed the reversed string without the symbols. I am asking if there is a way for me to remove these symbols while still using pointers? I have tried multiple variations on making the function with the pointers but the symbols still print at the end.

CodePudding user response:

That garbarge happens because you don't have null terminating character at the beginning of the string, thus you don't terminate when going backwards. I modified your code to keep sentinel zero character at 0-th position, and now your code works without bugs.

Also condition while (*p >= 0) should be replaced with while (*p).

Try it online!

#include <iostream>
using namespace std;

void reverse(char name[])
{
    char *p;
    p = name;

    while (*p != '\0')
    {
          p;
    }
    --p;
    while (*p)
    {
        cout << *p;
        --p;
    }
}

int main()
{
    char name[100];
    name[0] = 0;

    cout << "Please enter a string: ";
    cin.getline(name   1, sizeof(name) - 1);

    cout << "The reverse of the string is: ";

    reverse(name   1);

    return 0;
}

Input:

Please enter a string: Stack Overflow

Output:

The reverse of the string is: wolfrevO kcatS

CodePudding user response:

You're reading 100 characters into the string, which means there's a chance some trash input buffer values will be read too. This is where the symbols come from. Since you're using char arrays, maybe instead of getline use something like this:

char c = getchar();
int i = 0;
while(c != '\n'){
    name[i] = c;
    c= getchar();
    i  ;
}
name[i  ] = '\0'

This way you'll only read what you need to read, and will have the terminating character '\0' at the end of the string. Bear in mind there's probably a cleaner solution using getline tho. Either way, the problem is that you're reading more values then you want to read into the char array, and since you're directly accessing memory you need to figure out a way to add a '\0' after the desired string, so the method knows when to stop - I'm guessing char arrays are implemented in such a way to secure this always happens, hence the reason it works with char arrays but not with pointers.

CodePudding user response:

When you use

while (*p >= 0)
{
  cout << *p;
  --p;
}

you seem to assume that the space just before the beginning of the array is occupied by something negative; this is not a safe assumption, and the loop can iterate past that point, printing whatever binary junk happens to be in that region of memory. I say it can, because dereferencing a pointer into unallocated space like that is undefined behavior. It can do anything; it can terminate the loop so that the program appears to work correctly, it can print gibberish, it can crash you computer.

If you want to stop at the beginning of the given string, look for the beginning of the given string:

do
{
  --p;
  cout << *p;
}
while (p != name);

CodePudding user response:

I sincerely recommend to use the algorithm Depth first search to solve your problem.

#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int maximumSize=40;
vector<int> visited(maximumSize, 0);
void depthFirstSearch(int current, int previous, string input, string& output)
{
    if(visited[current]==1)
    {
        return;
    }
    visited[current]=1;
    for(int next=current; next<input.size();   next)
    {
        if(next==previous)
        {
            continue;
        }
        depthFirstSearch(next, current, input, output);
    }
    output.push_back(input[current]);
    if(current==0)
    {
        for(int index=0; index<input.size();   index)
        {
            cout<<output[index];
        }
    }
    return;
}
int main()
{
    string inputString="Stack Overflow", reverseString;
    depthFirstSearch(0, -1, inputString, reverseString);
    return 0;
}

Here is the result:

wolfrevO kcatS
  • Related