1

Trying to reverse the order of the characters input. I'm getting really close but no cigar.

#include <iostream>
using namespace std;

const int MAX = 10;

int main()
{
    char a[MAX], next;
    int index = 0;

    cout << "Please enter in up to 10 letters ending with a period: " << endl;
    cin >> next;

    while((next != '.') && (index < 10))
    {
        a[index] = next;
        index++;
        cin >> next;
        //cout << " " << next << endl;
    }

    int numbers_used = index;
    for(index = 0; index <= numbers_used; index++)
    {
        a[index] = a[numbers_used -1];
        numbers_used--;
        cout << a[index] << " " << endl;
    }
}

I'm getting everything but the last switch and even though my code is not as clean I'm failing to see where I'm going wrong.

The book code is:

for(index = numbers_used -1; index >= 0; index--)
     cout<<a[index];
cout<< endl;

and why is it index = numbers_used - 1 ?? Since numbers_used was set to index and index was initialized at 0 and not 1 wouldn't I want to run the loop "numbers_used" amount of times? What am I missing?

5
  • Won't your code end up overwriting the first half of the string? Commented Jul 23, 2014 at 16:54
  • once you get to the middle, you read values you already overwrote. work on a copy, or swap item up to half Commented Jul 23, 2014 at 16:54
  • You need an intermediate variable when swapping. The reason the book code works is they aren't changing the array as they are reading it. Commented Jul 23, 2014 at 17:04
  • Actually what you meant to do? It is very unclear to me. Commented Jul 23, 2014 at 19:00
  • If this is code in a textbook for C++, change the book. This is not how you write C++. Commented Jul 24, 2014 at 8:01

7 Answers 7

2

Try this:

char* flip(char* str, int len) {
    for(int x=0; x<(len/2); x++) {
        swap(str[x], str[len-x-1]);
    }
    return str;
}

As of right now, after you get to the middle of the string, you'll have overwritten the values that you would need to copy to the second half. With a string like "FooBarBiz", your code will produce the following over iterations (I've put spaces in to try and make things clearer):

1:  FooBarBiz
2: z ooBarBiz
3: zi oBarBiz
4: ziB BarBiz
5: ziBr arBiz
6: ziBra rBiz
7: ziBrar Biz
     ...

The code I posted however, uses the c++ swap function to swap the complimentary values, that way there are no lost values (we're not doing any overwriting), and you won't need to store the whole string in a placeholder variable. Does this make sense?

Sign up to request clarification or add additional context in comments.

3 Comments

Second index should be len - x - 1, not len - x.
Im sure this will be helpful down the road for me
@atrain if this was the correct answer, please accept it. If not, please let me know why it's not so that I can attempt to further help you.
0

If you want to reverse the list you have to start from the last element and decrease the index .

5 Comments

that to will overwrite half the string
@sp2danny: not change it; just print it from the last element
but thats already the book-suggested solution, and not what he wanted to accomplish
Am I not starting at the end when I set a[index] = a[numbers_used -1]?
Yes, but your implementation is too 'fast'; no need to decrease 'numbers_used'
0

You can approach this in at least two different ways. You can reverse the order of the string and then print, or you can leave the original string unmodified and simply print in reverse. I'd recommend the latter approach, in which case all you'd need to do is to change your last for loop to this:

    for(index = 0; index < numbers_used; index++)
    {
        cout << a[numbers_used-index-1] << " " << endl;
    }

4 Comments

This will produce an error on the last step in the loop.
<= should just be <
Follow up: Why in the book code in the for loop is it index = numbers_used - 1 ?? If I input a b c . index = 3 or 4. It must be 4 correct. The period counts toward the cycle/index total?
Your existing code counts up from 0, while the book code counts down from the end. So in this modified version, we use a[numbers_used-index-1] and the book version simply uses a[index]. The effect is identical, with the only difference being that the book code is a little more efficient since it does not require the subtraction each iteration.
0

Wouldn't it be easier this way ?

#include<iostream>
#include<string>

using namespace std;

const int MAX = 5;

int main()
{
    char a[MAX], next;
    int index = 0;
    bool period = false;

    cout << "Please enter in up to 10 letters ending with a period: " << endl;



    for(int i = 0; i < MAX && !period; i++)
    {       
        cin >> next;        
        if(next != '.')
        {
            a[i] = next;        // put the value into the array
            index++;
        }
        else
            period = true;      
    }    

    for(int i = index - 1; i >= 0 ; i--)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    return 0;
}

Comments

0

The problem can be solved by using the iterators from the standard library. The BidirectionalIterator as for example offered by std::string, std::list or std::vector can be traversed in both directions.

Using a std::string the solution could be:

#include <iostream>
#include <string>

using namespace std;

int main(int, char**) {
    char n = 0;
    string a;

    while (n != '.' && a.size() < 10) {
        cin >> n;
        if (n != '.') {
            a.push_back(n);
        }
    }

    for (string::reverse_iterator it = a.rbegin(); it != a.rend(); ++it) {
        cout << *it << endl;
    }
}

4 Comments

Note you don't need a vector to have a reverse iterator, just a bidirectional iterator.
Indeed, a list<char> would suffice. Or did you mean something different?
Well, std::string is probably going to be the best choice. My only point was that it's not just limited to std::vector, as the answer kind of suggests.
Ok, i tried to clarify the answer, to be more general.
0

I will start by saying: use std::string instead of C-style strings - it's universally less messy and more flexible.

Still, let's go with C-style strings since that's how you are attempting to do it and apparently your textbook also.

I won't comment on the way the user input is read, because I'm not sure if it's copied from the textbook (yikes!!) or you've done it yourself either way I find it to be pointless and wrong because it can lead to several problems. Note that the given book solution only prints out the characters in the reversed order and doesn't reverse the character array itself. You are apparently trying to reverse it.

Your solution is decrementing the numbers_used variable inside the for loop itself. This is a very bad idea since that variable is used in the conditional statement of the for loop. This means the loop will stop before it has iterated over the whole array. Even if the loop worked properly you still wouldn't have reversed the array since once this line executes

a[index] = a[numbers_used -1];

the original value of a[index] is overwritten and forgotten.

I'll try and write a simple solution to reverse a character array for a beginner:

#include <iostream>
#include <cstring> //getline, strlen
using namespace std;

const int MAX_LETTERS = 10;

int main() {
    char a[MAX_LETTERS + 1]; //since it's zero terminated

    cout << "Enter at most " << MAX_LETTERS << "characters (anything over " <<
        MAX_LETTERS << " will be truncated):\n";
    cin.getline(a, MAX_LETTERS + 1);

    int length = strlen(a); //returns length of input
    int last_char = length - 1;
    //reverse array
    for (int i = 0; i < length / 2; i++) {
        char temp = a[i];
        a[i] = a[last_char];
        a[last_char] = temp;
        last_char--;
    }
    //print array
    for (int i = 0; i < length; i++)
        cout << a[i];

    return 0;
}

Read this tutorial on C style strings, it will help you a lot.

Comments

0

The last for loop in your code is

int numbers_used = index;
for(index = 0; index <= numbers_used; index++)
{
    a[index] = a[numbers_used -1];
    numbers_used--;
    cout << a[index] << " " << endl;
}

If we consider 10 letters abcdefghij and according to your code the numbers_used=10after first loop.So in second loop

//In for loop
//index=0
a[index]=a[numbers_used-1]; // a[0]=a[9] => a[0]=j
numbers_used--; //numbers_used=9;
//index=1
a[index]=a[numbers_used-1]; //a[1]=a[8] => a[1]=i
numbers_used--; //numbers_used=8;
//index=2
a[index]=a[numbers_used-1]; //a[2]=a[7] => a[1]=h
numbers_used--; //numbers_used=7;
//index=3
a[index]=a[numbers_used-1]; //a[3]=a[6] => a[1]=g
numbers_used--; //numbers_used=6;
//index=4
a[index]=a[numbers_used-1]; //a[4]=a[5] => a[4]=f
numbers_used--; //numbers_used=5;
//index=5
a[index]=a[numbers_used-1]; //a[5]=a[5] => a[5]=e
numbers_used--; //numbers_used=4;
// index=6 and numbers_used becomes 4 => index <= numbers_used condition is violated 
so you will out of for loop.

This is why u cant get through. And in the second code i,e in the Book.

for(index = numbers_used -1; index >= 0; index--)
   cout<<a[index];
cout<< endl;

The numbers_used value is 10 but a[9] is the last value in the array so index is assigned to numbers_used-1. so that you can print from a[9] to a[0].

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.