tags:

views:

340

answers:

3
#include<string>
...
string in;

//How do I store a string from stdin to in?
//
//gets(in) - 16 cannot convert `std::string' to `char*' for argument `1' to 
//char* gets (char*)' 
//
//scanf("%s",in) also gives some weird error

Similarly, how do I write out in to stdout or to a file??

+7  A: 

You are trying to mix C style I/O with C++ types. When using C++ you should use the std::cin and std::cout streams for console input and output.

#include<string>
#include<iostream>
...
std::string in;

std::cin >> in;
std::cout << out;

But when reading a string std::cin stops reading as soon as it encounters a space or new line. You may want to use getline to get a entire line of input from the console.

std::getline (cin, in);

You use the same methods with a file (when dealing with non binary data).

std::ofstream ofs('myfile.txt');

ofs << myString;
Yacoby
+1  A: 

C++ strings must be read and written using >> and << operators and other C++ equivalents. However, if you want to use scanf as in C, you can always read a string the C++ way and use sscanf with it:

std::string s;
std::getline(cin, s);
sscanf(s.c_str(), "%i%i%c", ...);

The easiest way to output a string is with:

s = "string...";
cout << s;

But printf will work too: [fixed printf]

printf("%s", s.c_str());

The method c_str() returns a pointer to a null-terminated ASCII string, which can be used by all standard C functions.

Michał Trybus
Your use of printf is unsafe, it should be `printf("%s", s.c_str());` to prevent buffer overflows.
LiraNuna
You're right, I'll correct it.
Michał Trybus
+1  A: 

There are many way to read text from stdin into a std::string. The thing about std::strings though is that they grow as needed, which in turn means they reallocate. Internally a std::string has a pointer to a fixed-length buffer. When the buffer is full and you request to add one or more character onto it, the std::string object will create a new, larger buffer instead of the old one and move all the text to the new buffer.

All this to say that if you know the length of text you are about to read beforehand then you can improve performance by avoiding these reallocations.

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

// ...
    // if you don't know the length of string ahead of time:
    string in(istreambuf_iterator<char>(cin), istreambuf_iterator<char>());

    // if you do know the length of string:
    in.reserve(TEXT_LENGTH);
    in.assign(istreambuf_iterator<char>(cin), istreambuf_iterator<char>());

    // alternatively (include <algorithm> for this):
    copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(),
         back_inserter(in));

All of the above will copy all text found in stdin, untill end-of-file. If you only want a single line, use std::getline():

#include <string>
#include <iostream>

// ...
    string in;
    while( getline(cin, in) ) {
        // ...
    }

If you want a single character, use std::istream::get():

#include <iostream>

// ...
    char ch;
    while( cin.get(ch) ) {
        // ...
    }
wilhelmtell