2

I'm writing a program that reads user input and stores the value in a string. The value is supposed to be assigned to two char arrays, one of which is supposed to hold the characters in reversed order. However, the values in the reversed array don't show up in the terminal when I run the program. I also want to note that I am trying to achieve this without using pointers.

I've tried using a separate for loop together with a static int that gets incremented by 1 every iteration for reversed[str.length()] but the result stays the same. I've tested to output the values one by one, and somehow the characters show up in the terminal that way. I reckon that the values are assigned to the array after all, but aren't displayed when trying to output the whole text string at once. An explanation for why that is would be greatly appreciated!

Inside main():

string str;

cout << "Enter a word: ";
cin >> str;

cout << flush;

char input[str.length()];
char reversed[str.length()];

for(int i = 0; i <= str.length(); i++) {
    input[i] = str[i];
    reversed[i] = str[str.length() - i];
}

cout << "Your word: " << input << endl;
cout << "Reversed: " << reversed << endl;


Output:

Enter a word: hello

Your word: hello

Reversed: 

7
  • 1
    std::reverse(begin(str), end(str));, done. Commented Jun 26, 2019 at 9:07
  • To be pedantic, you can't access an array element without using pointers (whenever you use the name of the array in an indexing expression, it decays into a pointer). However, we know what you mean. Commented Jun 26, 2019 at 9:07
  • 1
    @dyukha Technically, str[str.length()] is undefined behavior, due to indexing str out of bounds. Commented Jun 26, 2019 at 9:09
  • @AlgirdasPreidžius, Yeah, I remembered that it's not C strings and removed the comment Commented Jun 26, 2019 at 9:10
  • @AlgirdasPreidžius it actually isn't, the standard has provision for the implicit nul-terminator. You can even write it over. Commented Jun 26, 2019 at 9:11

3 Answers 3

3

Copying the whole string including the null-terminator like this is correct since C++11 (before, accessing str[str.size()] would be undefined behavior). However, you also include that null terminator when you reverse the string. So as a result, the null terminator is the first character in your reversed string. This means that the string will be considered empty.

Instead, I would change the loop to this:

for (int i = 0; i < str.length(); i++) { // < instead of <=
    input[i] = str[i];
    reversed[i] = str[str.length() - i - 1]; // note the -1
}

Which copies the strings without the null terminator, and then you can set those manually:

input[str.length()] = '\0';
reversed[str.length()] = '\0';

Also, since the char array needs to hold the null-terminaror, its length should be str.length()+1.


On a side node, char input[str.length()]; is a so-called Variable-length array, which is not part of C++, but some compilers allow it nevertheless. It might not work if you compile the program using a different compiler.

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

4 Comments

Ah. My answer is wrong! I'll leave it up though, because I consider the warning that the OP needs to allocate enough space for the null terminator useful, and the discussion that variable length arrays are not actually C++. (If you want to copy that bit from my answer, please do.)
@MartinBonner I also only recently learned that accessing it with pos == size() is valid now. You say that your answer is wrong, but it's worth my upvote for the elaborate background information and the recommendation to not do it this way (I hope OP's task is of educational nature, because as Quentin point out, std::reverse(begin(str), end(str)); should be the solution in any practical situation).
It has to be educational. Otherwise the "without pointers" restriction makes absolutely no sense at all.
That's right, I'm currently following a book that has programming exercises at the end of every chapter. I'm currently only in chapter 3 and pointers aren't introduced until the next chapter, so I made the assumption that the author's intention was to ask the reader to solve the tasks by using only concepts introduced until that point.
2

Edit: The answer below is wrong for C++11 and beyond. However there is some useful discussion of "need to allocate space" and "variable length arrays aren't C++".

Your problem is

for(int i = 0; i <= str.length(); i++) {
    input[i] = str[i];
    reversed[i] = str[str.length() - i];
}

Remember that it is only legal to access str[0] upto and including str[str.length()-1] (and if length is zero, it's not legal to access any element).

On the first iteration of the loop, you access one beyond the end of the string when you assign to reversed. On the last iteration of the loop, you access one beyond the end of the string when you assign to input.

You need to run your loop, and then (after the loop) add a null terminator at the end of both input and reversed.

You also need to leave space in the variables for that null terminator.

Finally, you should be aware that:

char input[str.length()+1];
char reversed[str.length()+1];

is not actually legal C++. Array dimensions have to be compile time constants. There are a number of solutions to this problem:

  • Use std::string. Holding text is what std::string is for.
  • Use std::vector. This is a good solution to the general problem of holding a variable sized array of something.
  • Go ahead and use the variable sized array anyway, while being aware this may make porting to other platforms harder. If this is a school exercise, and you have been taught to do this, that is probably the right solution.

2 Comments

This has not been the case since C++11. It is indeed the reason for the output being blank though.
@Quentin: Yes, I had missed that!
1

[1] Improper length of arrays. Length of array should be 1 more than the length of string in order to properly terminate the string which will be store in the array. char input[str.length()]; //incorrect char reversed[str.length()]; //incorrect char input[str.length() + 1]; //correct char reversed[str.length() + 1]; //correct

[2] Array indexes start from 0. Therefore, if a string is of length 5 then the valid indexes are from 0 to 4. Index 5 is used to store the string terminating character \0. Therefore, the for loop should be working on indexes 0 to 4. for(int i = 0; i < str.length(); i++) //note "i < str.length()" { input[i] = str[i]; reversed[i] = str[str.length() - 1 - i]; //note -1 }

[3] Now, properly NULL terminate the strings. input[str.length()] = '\0'; reversed[str.length()] = '\0';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.