2010-11-16 27 views
17

Tôi có một văn bản trong một đối tượng chuỗi std ::. Văn bản bao gồm một số dòng. Tôi muốn lặp qua dòng văn bản bằng dòng sử dụng STL (hoặc Boost). Tất cả các giải pháp tôi đưa ra dường như là xa thanh lịch. Cách tiếp cận tốt nhất của tôi là phân tách văn bản ở ngắt dòng. Có một giải pháp thanh lịch hơn không?C++: Làm thế nào để lặp qua một văn bản trong một std :: chuỗi dòng phù hợp với STL?

UPDATE: Đây là những gì tôi đang tìm kiếm:

std::string input; 
// get input ... 
std::istringstream stream(input); 
std::string line; 
while (std::getline(stream, line)) { 
    std::cout << line << std::endl; 
} 

tôi nghĩ rằng tôi đã thử nó. Tôi đã nhận được một lỗi biên dịch và ném nó đi. Để nhanh chóng!

+0

Bạn đang tìm kiếm "thanh lịch hơn" như C# 's foreach "foreach (chuỗi dòng trong dòng)"? Chính xác thì bạn đã thử gì. C++ có thể cảm thấy 'không thích hợp' nếu bạn quen với các ngôn ngữ bậc cao hoặc năng động, nhưng trong C++ "thanh lịch" không bao giờ được trao cho bạn, bạn thường phải tự mình lập trình. – Crisfole

+1

Nó có thể không được * khá * một bản sao chính xác, nhưng bạn cũng có thể muốn xem: http://stackoverflow.com/questions/1567082/how-do-i-iterate-over-cin-line-by-line -in-c –

+0

Sẽ tốt hơn nếu bạn trả lời câu hỏi của riêng mình thay vì cập nhật nó. Việc cập nhật có thể gây nhầm lẫn cho người đọc trong tương lai ... – Wolf

Trả lời

17

Tại sao bạn giữ văn bản trong tệp nguồn của mình? Giữ nó trong một tập tin văn bản riêng biệt. Mở nó với std :: ifstream và lặp trên nó với while(getline(...))

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::ifstream fin("MyText.txt"); 
    std::string file_line; 
    while(std::getline(fin, file_line)) 
    { 
     //current line of text is in file_line, not including the \n 
    } 
} 

Ngoài ra, nếu các văn bản HAS là trong một dòng std::string biến đọc bởi dòng sử dụng std::istringstream một cách tương tự

Nếu câu hỏi của bạn là làm thế nào để đưa các văn bản lexially vào mã của bạn mà không sử dụng +, xin lưu ý rằng chuỗi liền kề literals được nối trước khi biên dịch, vì vậy bạn có thể làm điều này:

std::string text = 
    "Line 1 contents\n" 
    "Line 2 contents\n" 
    "Line 3 contents\n"; 
+5

Nếu bạn thực sự cần phải làm việc với một 'std :: string', bạn có thể bọc nó trong một' std :: stringstream' và áp dụng giải pháp của Armen. –

+0

Nếu dữ liệu đã là một chuỗi, bạn chỉ có thể sử dụng 'std :: stringstream' theo cách tương tự. –

+0

@Space: Tôi đã chỉnh sửa :) –

3

Nếu bạn muốn lặp lại line by line, như bạn nói, tại sao việc tách văn bản ở ngắt dòng không chính xác như bạn muốn?

Bạn không đăng mã hiển thị cách bạn đang thực hiện, nhưng cách tiếp cận của bạn có vẻ đúng để thực hiện những gì bạn đã nói. Tại sao nó cảm thấy kém hơn?

+0

Có vẻ như cách tiếp cận chính xác với tôi cũng vậy. – Simone

+0

Tôi muốn sử dụng một số giải pháp xây dựng trong STL. Kết thúc dòng AFAIK phụ thuộc vào nền tảng nên tôi muốn tránh giải pháp đó nếu có thể. –

+0

@Fair: Điều đó (cùng với mã hiện tại của bạn) có vẻ như thông tin cần phải có trong câu hỏi ban đầu. Đó là một mối quan tâm hợp lệ và có thể được giải quyết, nhưng chỉ khi bạn giải quyết nó head-on :) – KevenK

8

sử dụng Boost.Tokenizer :

std::string text("foo\n\nbar\nbaz"); 

typedef boost::tokenizer<boost::char_separator<char> > line_tokenizer; 
line_tokenizer tok(text, boost::char_separator<char>("\n\r")); 

for (line_tokenizer::const_iterator i = tok.begin(), end = tok.end(); 
    i != end ; ++i) 
    std::cout << *i << std::endl; 

in

foo 
bar 
baz 

Lưu ý rằng nó sẽ bỏ qua trên dòng sản phẩm nào, mà có thể hoặc không thể là những gì bạn muốn.

+0

Không sử dụng boost :: tokenizer cho một cái gì đó có thể được thực hiện với getline sắp xếp của giống như giết chết một con chim sẻ với một nuke? –

+0

Phụ thuộc vào những gì OP muốn làm. Giải pháp này khá ngắn và nó tạo ra một cặp các trình lặp có thể được trao cho các thuật toán STL. –

Các vấn đề liên quan