0

Can we accept and print a string like this in c++? This code is not working properly.

#include<iostream>
#include<string>
using namespace std;

 main()
{
 string a;char ch;
 for(int i=0;i<5;i++)
 {cin>>ch;
 a[i]=ch;
 }
a[5]='\0';
cout<<a;

}

I am able to print individual elements like a[1],a[2],etc but unable to print the entire string.Why?

Ajay Sabarish
  • 171
  • 2
  • 6

4 Answers4

0

If you want to take a string, you could do the following.

#include <iostream>

int main() {
    std::string str;

    std::getline(std::cin, str);

    std::cout << str;
}

Also, C++ automatically null terminates any string literal you use.

ChemiCalChems
  • 612
  • 12
  • 31
  • Sir,thank you very much for replying,but I added a null terminated string at the end,yet it is not working,can we not access elements of a string use [] operator?Am I not directly adding elements to it? And the input of the problem which I am tying involves elements entered with a space in between like 1 2 3 4,so how to accept these elements and store them in a string? – Ajay Sabarish May 26 '17 at 05:45
  • Why do you want to use a string? Why not use a vector and push back numbers to it? – ChemiCalChems May 26 '17 at 05:54
0

Well it's not really anywhere near best-practices but to fix your immediate issue you need to actually resize the string.

#include<iostream>
#include<string>

main()
{
  std::string a;char ch;
  a.resize(5); // <--- reserves memory
  for(int i=0;i<5;i++)
  {
    std::cin>>ch;
    a[i]=ch;
  }
  a[5]='\0'; //<-- unnecessary 
  st::cout<<a;
}

alternatively you can append the characters

#include<iostream>
#include<string>

main()
{
  std::string a;char ch;
  for(int i=0;i<5;i++)
  {
    std::cin>>ch;
    a+=ch;
  }
  std::cout<<a;
}
PeterT
  • 7,981
  • 1
  • 26
  • 34
  • Sir,thank you very much for replying,but why should we do it sir?Doesn't string automatically take care of memory and extends when necessary? – Ajay Sabarish May 26 '17 at 05:54
  • @AjaySabarish when you use `append` or `operator+=` or something like it, but the [`operator[]`](http://en.cppreference.com/w/cpp/string/basic_string/operator_at) doesn't do any bounds checking – PeterT May 26 '17 at 05:56
  • Wouldn't you rather use `reserve` not `resize`? `resize` will initialize to zeroes, `reserve` will just reserve the space without intialization – Dustin Nieffenegger May 26 '17 at 08:30
  • @DustinGoodson no, while you wouldn't be writing to random memory anymore, reserve would not update the size. So `a.size()` would still be wrong afterwards and would presumably not print – PeterT May 26 '17 at 10:46
0

The real problem here is not that you can't read or can't print the string, is that you are writing to unallocated memory. operator[], which is what you are using when you do something like a[i]=ch, does not do any kind of boundary checking and thus you are causing undefined behavior. In my machine, nothing is printed, for instance.

In short, you need to make sure that you have space to write your characters. If you are certain that you are going to read 5 characters (and adding a \0 at the end, making it 6 in length), you could do something like this:

std::string a(6, '\0')

If you are uncertain of how many characters you are going to read, std::string is ready to allocate space as need, but you need to use std::push_back to give it a chance to do so. Your loop contents would be something like:

cin >> ch;
a.push_back(ch);

If you are uncertain where the std::string object is coming from (as in, this is library code that accepts a std::string as an argument, you could use at(i) (e.g, a.at(i) = ch instead of a[i] = ch), which throws an exception if it is out of range.

Leonardo
  • 1,834
  • 1
  • 17
  • 23
-1

You can print the string like this

#include<iostream>
#include<string>
using namespace std;
int main()
{
string a;char ch;
for(int i=0;i<5;i++)
{
cin>>ch;
a.push_back(ch); 
}
a.push_back('\0');
cout << a;
return 0;
}
Amol
  • 47
  • 1
  • 8