2010-04-11 4 views
11
#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 

Podobnie, jak mogę napisać in na standardowe wyjście lub do pliku?Jak odczytać i napisać ciąg STL C++?

Odpowiedz

21

Próbujesz mieszać we/wy w stylu C z typami C++. Używając C++, należy używać strumieni std :: cin i std :: cout do wejścia i wyjścia konsoli.

#include<string> 
#include<iostream> 
... 
std::string in; 
std::string out("hello world"); 

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

Ale przy odczycie struny std :: cin przestaje czytać, gdy tylko napotka spację lub nową linię. Możesz użyć getline, aby uzyskać całą linię danych wejściowych z konsoli.

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

Używa się tych samych metod z plikiem (w przypadku danych nie binarnych).

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

ofs << myString; 
0

C++ ciągi muszą być odczytywane i zapisywane za pomocą >> i << operatorów i inne ekwiwalenty C++. Jednakże, jeśli chcesz używać scanf jak w C, zawsze można odczytać ciąg sposób C++ i używać sscanf z nim:

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

najprostszy sposób na wyjściu ciąg jest z:

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

Ale printf będzie działać zbyt: [fixed printf]

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

Sposób c_str() zwraca wskaźnik do null-ter minowany łańcuch ASCII, który może być używany przez wszystkie standardowe funkcje C.

+2

Korzystanie z printf jest niebezpieczny, należy 'printf ("% s ", s.c_str());' aby zapobiec przepełnieniu bufora. – LiraNuna

+0

Masz rację, poprawię to. –

3

Istnieje wiele sposobów czytania tekstu ze standardowego wejścia na standard std::string. Chodzi o to, że rozwijają się w miarę potrzeb, co z kolei oznacza ich ponowne przydzielenie. Wewnętrznie std::string ma wskaźnik do bufora o stałej długości. Kiedy bufor jest pełny i żądasz dodania do niego jednego lub więcej znaków, obiekt std::string utworzy nowy, większy bufor zamiast starego i przeniesie cały tekst do nowego bufora.

Wszystko to, aby powiedzieć, że jeśli znasz długość tekstu, który zamierzasz przeczytać wcześniej, możesz poprawić wydajność, unikając tych ponownych przydziałów.

#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)); 

Wszystkie powyższe skopiuje wszystkie teksty znalezione w stdin, aż do końca pliku. Jeśli chcesz tylko jednej linii, użyj std::getline():

#include <string> 
#include <iostream> 

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

jeśli chcesz pojedynczy znak, użyj std::istream::get():

#include <iostream> 

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