ifstream
के साथ खोले गए फ़ाइल में वर्तमान पंक्ति की लाइन संख्या प्राप्त करने का सबसे अच्छा तरीका क्या होगा? इसलिए मैं डेटा में पढ़ रहा हूं और मुझे उस लाइन नंबर को स्टोर करने की आवश्यकता है, जिस पर यह है कि यदि मैं विनिर्देशों से मेल नहीं खाता तो मैं इसे बाद में प्रदर्शित कर सकता हूं।सी ++ में किसी फ़ाइल से लाइन नंबर कैसे प्राप्त करें?
उत्तर
किसी इस्टस्ट्रीम बिंदु से कोई लाइन नंबर नहीं है। यदि आप लाइन लाइन में लाइन लाइन में पढ़ते हैं, तो आपको बस इसे ट्रैक रखना होगा।
प्रत्येक पंक्ति को एक-एक करके पढ़ने के लिए std::getline
का उपयोग करें। आपके द्वारा पढ़ी गई लाइनों की संख्या को इंगित करने वाला एक पूर्णांक रखें: इसे शून्य पर प्रारंभ करें और प्रत्येक बार जब आप std::getline
पर कॉल करते हैं और यह सफल होता है, तो इसे बढ़ाएं।
तो आप std::streambuf
से व्युत्पन्न वर्ग इस्तेमाल कर सकते हैं std::getline
अपने आप को सीमित करने के लिए नहीं आप करते तो चाहते हैं, और जो वर्तमान पंक्ति संख्या का ट्रैक रखता है:
class CountingStreamBuffer : public std::streambuf { /* see below */ };
// open file
std::ifstream file("somefile.txt");
// "pipe" through counting stream buffer
CountingStreamBuffer cntstreambuf(file.rdbuf());
std::istream is(&cntstreambuf);
// sample usage
is >> x >> y >> z;
cout << "At line " << cntstreambuf.lineNumber();
std::getline(is, str);
cout << "At line " << cntstreambuf.lineNumber();
यहाँ एक है CountingStreamBuffer
का नमूना कार्यान्वयन:
#include <streambuf>
class CountingStreamBuffer : public std::streambuf
{
public:
// constructor
CountingStreamBuffer(std::streambuf* sbuf) :
streamBuf_(sbuf),
lineNumber_(1),
lastLineNumber_(1),
column_(0),
prevColumn_(static_cast<unsigned int>(-1)),
filePos_(0)
{
}
// Get current line number
unsigned int lineNumber() const { return lineNumber_; }
// Get line number of previously read character
unsigned int prevLineNumber() const { return lastLineNumber_; }
// Get current column
unsigned int column() const { return column_; }
// Get file position
std::streamsize filepos() const { return filePos_; }
protected:
CountingStreamBuffer(const CountingStreamBuffer&);
CountingStreamBuffer& operator=(const CountingStreamBuffer&);
// extract next character from stream w/o advancing read pos
std::streambuf::int_type underflow()
{
return streamBuf_->sgetc();
}
// extract next character from stream
std::streambuf::int_type uflow()
{
int_type rc = streamBuf_->sbumpc();
lastLineNumber_ = lineNumber_;
if (traits_type::eq_int_type(rc, traits_type::to_int_type('\n')))
{
++lineNumber_;
prevColumn_ = column_ + 1;
column_ = static_cast<unsigned int>(-1);
}
++column_;
++filePos_;
return rc;
}
// put back last character
std::streambuf::int_type pbackfail(std::streambuf::int_type c)
{
if (traits_type::eq_int_type(c, traits_type::to_int_type('\n')))
{
--lineNumber_;
lastLineNumber_ = lineNumber_;
column_ = prevColumn_;
prevColumn_ = 0;
}
--column_;
--filePos_;
if (c != traits_type::eof())
return streamBuf_->sputbackc(traits_type::to_char_type(c));
else
return streamBuf_->sungetc();
}
// change position by offset, according to way and mode
virtual std::ios::pos_type seekoff(std::ios::off_type pos,
std::ios_base::seekdir dir,
std::ios_base::openmode mode)
{
if (dir == std::ios_base::beg
&& pos == static_cast<std::ios::off_type>(0))
{
lastLineNumber_ = 1;
lineNumber_ = 1;
column_ = 0;
prevColumn_ = static_cast<unsigned int>(-1);
filePos_ = 0;
return streamBuf_->pubseekoff(pos, dir, mode);
}
else
return std::streambuf::seekoff(pos, dir, mode);
}
// change to specified position, according to mode
virtual std::ios::pos_type seekpos(std::ios::pos_type pos,
std::ios_base::openmode mode)
{
if (pos == static_cast<std::ios::pos_type>(0))
{
lastLineNumber_ = 1;
lineNumber_ = 1;
column_ = 0;
prevColumn_ = static_cast<unsigned int>(-1);
filePos_ = 0;
return streamBuf_->pubseekpos(pos, mode);
}
else
return std::streambuf::seekpos(pos, mode);
}
private:
std::streambuf* streamBuf_; // hosted streambuffer
unsigned int lineNumber_; // current line number
unsigned int lastLineNumber_;// line number of last read character
unsigned int column_; // current column
unsigned int prevColumn_; // previous column
std::streamsize filePos_; // file position
};
एक अक्षम लेकिन मृत सरल तरीका है एक ऐसा फ़ंक्शन है जिसने स्ट्रीम दिया है, यह धारा की शुरुआत से वर्तमान स्थिति तक नए लाइन वर्णों की गणना करता है। यह अक्षम है क्योंकि यदि आप कई स्ट्रीम पोजिशन के लिए लाइन जानना चाहते हैं, तो आपको प्रत्येक बार स्ट्रीम की शुरुआत से गिनती शुरू करने के लिए इसे कई बार कॉल करना होगा। कुछ कोड में मैं काम कर रहा हूं, अगर मुझे अमान्य इनपुट का सामना करना पड़ता है तो मुझे केवल लाइन नंबर जानने में दिलचस्पी है, उस मामले में आयात तुरंत रद्द कर दिया जाता है। चूंकि फ़ंक्शन को केवल एक बार अक्षमता कहा जाता है जब वास्तव में कोई समस्या नहीं होती है।
विधि केint getCurrentLine(std::istream& is)
{
int lineCount = 1;
is.clear(); // need to clear error bits otherwise tellg returns -1.
auto originalPos = is.tellg();
if (originalPos < 0)
return -1;
is.seekg(0);
char c;
while ((is.tellg() < originalPos) && is.get(c))
{
if (c == '\n') ++lineCount;
}
return lineCount;
}
लाभ यह है कि कोई बदलाव नहीं जगह है जहाँ धारा का निर्माण किया है पर जरूरत है है, तो आप सिर्फ समारोह जहां आपको उसकी आवश्यकता कॉल करने की आवश्यकता:
यहाँ ऐसा करने के लिए मेरे कोड है । निम्नलिखित एक पूर्ण उदाहरण है:
#include <iostream>
#include <sstream>
int getCurrentLine(std::istream& is)
{
int lineCount = 1;
is.clear(); // need to clear error bits otherwise tellg returns -1.
auto originalPos = is.tellg();
if (originalPos < 0)
return -1;
is.seekg(0);
char c;
while ((is.tellg() < originalPos) && is.get(c))
{
if (c == '\n') ++lineCount;
}
return lineCount;
}
void ReadDataFromStream(std::istream& s)
{
double x, y, z;
while (!s.fail() && !s.eof())
{
s >> x >> y >> z;
if (!s.fail())
std::cout << x << "," << y << "," << z << "\n";
}
if (s.fail())
std::cout << "Error at line: " << getCurrentLine(s) << "\n";
else
std::cout << "Read until line: " << getCurrentLine(s) << "\n";
}
int main(int argc, char* argv[])
{
std::stringstream s;
s << "0.0 0.0 0.0\n";
s << "1.0 ??? 0.0\n";
s << "0.0 1.0 0.0\n";
ReadDataFromStream(s);
std::stringstream s2;
s2 << "0.0 0.0 0.0\n";
s2 << "1.0 0.0 0.0\n";
s2 << "0.0 1.0 0.0";
ReadDataFromStream(s2);
return 0;
}
- 1. किसी दिए गए लाइन नंबर
- 2. कैसे एक लाइन नंबर
- 3. PHP लॉगिंग ईवेंट से लाइन नंबर प्राप्त करें
- 4. स्टैक ट्रेस लाइन नंबर से वास्तविक जेएसपी लाइन नंबर प्राप्त करना?
- 5. मैं टेक्स्ट फ़ाइल में लाइन नंबर से किसी विशिष्ट पंक्ति को कैसे प्रतिस्थापित कर सकता हूं?
- 6. फ्लोट नंबर से अंश कैसे प्राप्त करें?
- 7. लाइन नंबर
- 8. सी # अपवाद नहीं लाइन नंबर
- 9. रिलीज मोड में पीडीबी से लाइन नंबर प्राप्त करना
- 10. विम लाइन नंबर - डिफ़ॉल्ट रूप से उन्हें कैसे चालू करें?
- 11. पार्सिंग वाईएएमएल, लाइन नंबर
- 12. लाइन नंबर दृश्य
- 13. किसी अनुक्रमित अनुक्रम में दिए गए पहले नंबर से पहले नंबर प्राप्त करें
- 14. फोनगैप में आईएमईआई नंबर कैसे प्राप्त करें?
- 15. यूनिक्स कमांड लाइन नंबर
- 16. लॉगबैक AyncAppender फ़ाइल और लाइन नंबर
- 17. मैं Dreamweaver CS4 में लाइन नंबर वापस कैसे प्राप्त करूं?
- 18. फ़ाइल से फ़ाइल का नाम कैसे प्राप्त करें * सी
- 19. वास्तविक डिवाइस से मोबाइल नंबर प्राप्त करें
- 20. कम संख्या में लाइन नंबर कैसे प्रदर्शित करें (जीएनयू)?
- 21. WPF RichTextBox लाइन नंबर
- 22. पायथन कमांड लाइन से फ़ाइलें प्राप्त करें
- 23. किसी ऑब्जेक्ट URL से फ़ाइल या ब्लॉब कैसे प्राप्त करें?
- 24. किसी .resx फ़ाइल प्रविष्टि से टिप्पणी कैसे प्राप्त करें
- 25. फ़ाइल नाम, लाइन नंबर और कॉलिंग फ़ंक्शन का फ़ंक्शन नाम प्रिंट करें - सी प्रोग
- 26. सी कॉम्प्लेक्स नंबर सी ++ में?
- 27. हार्ड डिस्क से सीरियल नंबर कैसे प्राप्त करें?
- 28. MyTQL में डेटटाइम को किसी नंबर पर कैसे परिवर्तित करें?
- 29. लिंक क्वेरी परिणाम में एक लाइन नंबर कैसे प्रोजेक्ट करें
- 30. मैक हार्ड डिस्क से सीरियल नंबर कैसे प्राप्त करें?
नोट: आप या तो लाइन ('std :: getline') द्वारा लाइन पढ़ सकते हैं या बस पास होने वाले \ n' वर्णों की संख्या को गिन सकते हैं। –
@ मैथियू: यह मान रहा है कि प्रत्येक '\ n' आपके प्लेटफॉर्म पर एक नई लाइन का प्रतीक है। मुझे नई लाइन पर कॉल ट्रैक करना बेहतर लगता है (एक साधारण रैपर करेगा ...) – rubenvb
@ रूबेनव: पाठ मोड में \ n' एक नई पंक्ति का प्रतिनिधित्व करता है, 'iostream' इसे बनाने के लिए लोकेल का उपयोग करता है (दोनों पढ़ने और लेखन)। यदि आप बाइनरी मोड में पढ़ते हैं, तो निश्चित रूप से कोई रूपांतरण नहीं होता है ... –