atrain
atrain

Reputation: 7

Beginner c++ array and loop?

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?

Upvotes: 1

Views: 138

Answers (7)

shashank
shashank

Reputation: 410

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].

Upvotes: 0

broda
broda

Reputation: 25

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.

Upvotes: 0

Djings
Djings

Reputation: 56

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;
    }
}

Upvotes: 0

Hoang Minh
Hoang Minh

Reputation: 1220

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;
}

Upvotes: 0

Edward
Edward

Reputation: 7080

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;
    }

Upvotes: 0

scohe001
scohe001

Reputation: 15446

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?

Upvotes: 2

Igor Pejic
Igor Pejic

Reputation: 3698

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

Upvotes: 0

Related Questions