2010-11-16 29 views
17

Std :: string nesnesinde bir metin var. Metin birkaç satırdan oluşur. Metin satırını STL (veya Boost) kullanarak sıraya koymak istiyorum. Geldiğim tüm çözümler zarif olmaktan uzak görünüyor. En iyi yaklaşımım, metni satır sonlarında bölmek. Daha şık bir çözüm var mı?C++: STL ile bir std :: string satırındaki bir metnin üzerinde yineleme nasıl yapılır?

GÜNCELLEME: Bu aradığım buydu:

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

Ben zaten denedim düşündüm. Bir derleyici hatası aldım ve attı. Çabuk!

+0

siz 'foreach (hatlarında dize hattı)' C# 'ın foreach gibi "daha şık" arıyorsunuz? Tam olarak ne denedin? C++, dinamik veya daha yüksek seviyeli diller için kullanılıyorsa 'inelegant' hissedebilir, ancak C++ 'zarif' asla size teslim edilmez, genellikle zerafeti kendiniz programlamanız gerekir. – Crisfole

+1

O * oldukça * tam kopyası olmayabilir, ama aynı zamanda bakmak isteyebilirsiniz: http://stackoverflow.com/questions/1567082/how-do-i-iterate-over-cin-line-by-line -in-c –

+0

Güncelleştirmek yerine kendi sorunuzu yanıtlamak daha iyi olurdu. Güncelleme gelecekteki okuyucu için kafa karıştırıcı olabilir ... – Wolf

cevap

17

Neden kaynak dosyada metni tutarsınız? Ayrı bir metin dosyasında saklayın. std :: ifstream ile açın ve metin Sorunuz, benzer şekilde

yılında std::istringstream kullanarak çizgi ile bir std::string değişken okuma hattında olmak HAS eğer Alternatif 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 
    } 
} 

ile bitti yineleme

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

Gerçekten bir "std :: string" ile çalışmanız gerekiyorsa, bunu bir "std :: stringstream" içine sarın ve Armen'in çözümünü uygulayabilirsiniz. –

+0

Veri zaten bir dizeyse, std :: stringstream işlevini aynı şekilde kullanabilirsiniz. –

+0

@Space: Düzenledim :) –

3

Eğer dediğiniz gibi, döngü line by line istiyorsanız, neden çizgisinde metni tam olarak ne istediğinizi olmayacak sonları bölme ki? Sen bunu nasıl yaptığınızı gösteren kod sonrası yoktu, ama yaklaşımınız ne istediğini söylediğin gerçekleştirmek için doğru görünüyor

. Neden daha aşağı hissediyor?

+0

Bana da doğru yaklaşım gibi görünüyor. – Simone

+0

Bazı STL kurulum çözümlerini kullanmayı tercih ederim. AFAIK satır sonları platform bağımlıdır, bu yüzden mümkünse bu çözümü önlemek isterim. –

+0

@Fair: Bu (mevcut kodunuzla birlikte) asıl soruda olması gereken bilgiler gibi görünüyor. Bu, geçerli bir endişe ve ele alınabilir, ancak :) – KevenK

8

Kullanım Boost.Tokenizer: bunu böylece + kullanarak olmadan koduna lexially metni koymak nasıl, değişmezleri derleme önce birleştirilmiş olduğu bitişik dize unutmayın :

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; 

baskılar o ya ne istediğinizi olabilir de olmayabilir de boş hatlar, bölgenin atladığı

foo 
bar 
baz 

Not.

+0

Bir nuke ile bir serçe öldürme gibi getline sort-of ile yapılabilir bir şey için boost :: tokenizer kullanmıyor mu? –

+0

OP'nin yapmak istediği şeye bağlıdır. Bu çözüm oldukça kısadır ve STL algoritmalarına verilebilecek bir çift yineleyici sağlar. –

İlgili konular