Std :: LF, CR, CRLF?işlemek için ifstream
Özellikle istream& getline ( istream& is, string& str );
ilgileniyorum. Orada '\n' kaputun altında? tüm yeni satır kodlamaları dönüştürmek için söylemek ifstream yapıcı bir seçenektir getline
Ara ve incelikle tüm Satır sonları işlemek için mümkün olmak istiyorum.
GüncellemeAçıklık, hemen hemen her yerde derler ve hemen hemen her yerden giriş alacak bir kod yazmak istiyorum. Ender dosyalar dahil '\r' '\n'. Yazılımın tüm kullanıcılar için rahatsızlık en aza indirmek.
Kolay sorun için çözüm değil, ama standart doğru yol için, esnek bir şekilde tüm metin dosya biçimleri ele olarak hala merak ediyorum.
Tam bir çizgi getline
okur, bir '\n', bir dizeye. '\N' akış tüketilen, ama getline dize dahil değil. Şimdiye kadar idare etti, ama olabilir '\r' önce '\n' bu dize içine dahil olur.
three types of line endings metin dosyaları görülen vardır: '\n' geleneksel sona Unıx makineleri, '\r' (sanırım) eski Mac işletim sistemleri ve Windows kullanan bir çift, '\r' izleyerek '\n'.
Sorun getline
'\r' dize sonunda. bırakmasıdır
ifstream f("a_text_file_of_unknown_origin");
string line;
getline(f, line);
if(!f.fail()) { // a non-empty line was read
// BUT, there might be an '\r' at the end now.
}
Editf.good()
benim istediğim şey değil bu işaret için Neil için teşekkürler. !f.fail()
istiyorum.
Windows metin dosyaları için kolay olan bu elle ben de bu soruyu Düzenle çıkarın, ben. Ama birisi bir dosya sadece içeren yem olacak diye korkuyorum '\r'. Bu durumda, getline bütün dosya, tek bir hat olduğunu düşünerek tüketir herhalde!
.. ve hatta Unicode düşünüyor :-)
.. belki de Destek metin dosyası herhangi bir türü için bir satır aynı anda tüketmek için iyi bir yol var mı?
EditBu, Windows dosyalarını işlemek için kullanıyorum, ama yine de gerek yok hissediyorum! Ve bunun için çatal olmayacak '\r'-sadece dosyaları.
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}
CEVAP
Neil, "C çalışma zamanı doğru hat sözleşmesi biten belirli bir platform için ne olursa olsun çözmeli." belirttiği gibi
Ancak, insanlar farklı platformlar arasında metin dosyaları taşıyın, bu yeterli değil. Burada üç Satır sonları işleyen bir işlev ("\r", "\n" ve "\r\n"):
std::istream& safeGetline(std::istream& is, std::string& t)
{
t.clear();
// The characters in the stream are read one-by-one using a std::streambuf.
// That is faster than reading them one-by-one using the std::istream.
// Code that uses streambuf this way must be guarded by a sentry object.
// The sentry object performs various tasks,
// such as thread synchronization and updating the stream state.
std::istream::sentry se(is, true);
std::streambuf* sb = is.rdbuf();
for(;;) {
int c = sb->sbumpc();
switch (c) {
case '\n':
return is;
case '\r':
if(sb->sgetc() == '\n')
sb->sbumpc();
return is;
case EOF:
// Also handle the case when the last line has no line ending
if(t.empty())
is.setstate(std::ios::eofbit);
return is;
default:
t = (char)c;
}
}
}
Ve burada bir test programı
int main()
{
std::string path = ... // insert path to test file here
std::ifstream ifs(path.c_str());
if(!ifs) {
std::cout << "Failed to open the file." << std::endl;
return EXIT_FAILURE;
}
int n = 0;
std::string t;
while(!safeGetline(ifs, t).eof())
n;
std::cout << "The file contains " << n << " lines." << std::endl;
return EXIT_SUCCESS;
}
Hareket Gıt ile yeni bir şube için en ...
Java kullanarak.net.Ateş ve işlemek iç...
Belirli bir görev için git bir yama iş...
Nasıl ilerleme iletişim ve arka plan i...
Nasıl gıt sayısı işlemek için?...