2010-04-11 29 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 

Tương tự, làm cách nào để viết ra in thành giá trị hoặc tệp?Làm thế nào để đọc và viết một chuỗi STL C++?

Trả lời

21

Bạn đang cố gắng kết hợp kiểu I/O kiểu C với kiểu C++. Khi sử dụng C++, bạn nên sử dụng std :: cin và std :: cout stream cho giao diện điều khiển đầu vào và đầu ra.

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

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

Nhưng khi đọc chuỗi std :: cin dừng đọc ngay khi gặp phải dấu cách hoặc dòng mới. Bạn có thể muốn sử dụng getline để nhận toàn bộ dòng đầu vào từ bảng điều khiển.

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

Bạn sử dụng cùng phương pháp với tệp (khi xử lý dữ liệu nhị phân).

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

ofs << myString; 
0

C++ chuỗi phải được đọc và viết bằng >><< nhà khai thác và các khoản tương đương khác C++. Tuy nhiên, nếu bạn muốn sử dụng scanf như trong C, bạn luôn có thể đọc một chuỗi C++ cách và sử dụng sscanf với nó:

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

Cách dễ nhất để ra một chuỗi là với:

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

Nhưng printf sẽ làm việc quá: [printf cố định]

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

phương pháp c_str() trả về một con trỏ đến một null-ter chuỗi ASCII được khai thác, có thể được sử dụng bởi tất cả các hàm C chuẩn.

+2

Việc bạn sử dụng printf là không an toàn, nó phải được 'printf ("% s ", s.c_str());' để ngăn chặn tràn bộ đệm. – LiraNuna

+0

Bạn nói đúng, tôi sẽ sửa nó. –

3

Có nhiều cách để đọc văn bản từ stdin thành std::string. Những điều về std::string s mặc dù là chúng phát triển khi cần thiết, do đó có nghĩa là họ tái phân bổ. Bên trong một số std::string có con trỏ đến bộ đệm có độ dài cố định. Khi bộ đệm đầy và bạn yêu cầu thêm một hoặc nhiều ký tự vào bộ đệm, đối tượng std::string sẽ tạo bộ đệm mới, lớn hơn thay cho bộ đệm cũ và di chuyển tất cả văn bản sang bộ đệm mới.

Tất cả điều này để nói rằng nếu bạn biết độ dài của văn bản bạn sắp đọc trước đó thì bạn có thể cải thiện hiệu suất bằng cách tránh các phân bổ lại này.

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

Tất cả những điều trên sẽ sao chép tất cả văn bản được tìm thấy trong tiêu chuẩn, cho đến cuối tệp. Nếu bạn chỉ muốn có một dòng duy nhất, sử dụng std::getline():

#include <string> 
#include <iostream> 

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

Nếu bạn muốn có một nhân vật duy nhất, sử dụng std::istream::get():

#include <iostream> 

// ... 
    char ch; 
    while(cin.get(ch)) { 
     // ... 
    } 
Các vấn đề liên quan