0

I'm working on a C++ program that takes a string as an input and manipulates it in certain ways. This is the code:

string input;
cin >> input;
char arg = input[4]; //All inputs always have 5 characters
cout << arg << endl;

Input: add d

I was expecting it to print d to the screen but instead nothing is printed Also, for other inputs, I sometimes get weird characters (like y with two dots over it) as the output.

Why is this happening and how can it be rectified?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Ajmal
  • 107
  • 1
  • 12
  • Mind to post a [MCVE] that reproduces your problem please? – πάντα ῥεῖ Feb 12 '17 at 13:31
  • After fixing the typo, everything [works as intended](http://ideone.com/E2iBWf). – πάντα ῥεῖ Feb 12 '17 at 13:34
  • You wrote in the comment "all inputs always have 5 characters", but in fact your input 'add d' has only three characters (look at the first token). – Brandin Feb 12 '17 at 13:35
  • The problem lies with your input - the whitespace (after "add") terminates the input - leaving "add" as the value stored in `input` - so `input[4]` is accessing out of bounds and causing *undefined behavior* – UnholySheep Feb 12 '17 at 13:35
  • So how can I take in an input which contains whitespaces? – Ajmal Feb 12 '17 at 13:36
  • @Ajmal For that answer look here: http://stackoverflow.com/questions/1583652/how-to-read-cin-with-whitespace-up-until-a-newline-character – Brandin Feb 12 '17 at 13:39
  • @Ajmal Also, rather than writing a comment "inputs have 5 characters", try to verify that this is actually the case e.g. using an if or assert. Then you can get more information before asking a question such as "why is the length 3 when I think it should be 5". – Brandin Feb 12 '17 at 13:43
  • Compile with all warnings & debug info (`g++ -Wall -g`) then **use the debugger** (`gdb`) – Basile Starynkevitch Feb 12 '17 at 13:46
  • 1
    **−1** Posting invalid code (fixed that missing semicolon for you but still don't do that, don't type in code manually: copy and paste) – Cheers and hth. - Alf Feb 12 '17 at 13:51

3 Answers3

4

In your input string, the cin >> operator takes your string until the the space then it will terminate. So in your string only add would be present, so when you try to access the fourth character and print nothing will be displayed.

Try,

string input;    
getline(cin, input);    
char arg = input[4];    
cout << arg << endl;
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Alfran
  • 1,301
  • 1
  • 10
  • 19
3

Note that the extraction of operator<< for std::string stops at whitespace, so the value of input would be add, then char arg = input[4]; is UB.

... then reads characters from is and appends them to str as if by str.append(1, c), until one of the following conditions becomes true:

  • ...

  • std::isspace(c,is.getloc()) is true for the next character c in is (this whitespace character remains in the input stream).

You can use std::getline instead to read input containing whitespaces, it will read the string until the specified delimiter; the default one is the endline. e.g.

string input;
std::getline(std::cin, input);
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 2
    I don't see how the standard version matters. For a string with length 3, input[4] is always out of bounds. – Brandin Feb 12 '17 at 13:45
  • It should be noted that since C++11, `input[3]` would not be undefined behaviour but would indeed return a reference to a null character. However, modifying that reference is still undefined behaviour. In any case, `input[4]` is always undefined behaviour, because the internally used array has only 4 elements (`"add"` plus the null character). – Christian Hackl Feb 12 '17 at 14:04
0

In your example when you input (add d) only the characters before the space are considered. so there's garbage value in input[4]

If you want to input spaces, use double quotations.

#include <iostream>
using namespace std;
int main(void)
{
string input;
cin >> input;
char arg = input[4]; //All inputs always have 5 characters
cout << input.length() << endl;
cout << arg << endl;
}

if you pass add d, the string length will be 3, not 5. If you want to be able to input spaces, replace cin >> input; with std::getline(std::cin, input);

and you will get the desired results.

Zeyad Obaia
  • 686
  • 1
  • 6
  • 21