जवाबों:
सबसे पहले ifstream
:
#include <fstream>
std::ifstream infile("thefile.txt");
दो मानक विधियाँ हैं:
मान लें कि हर पंक्ति में दो नंबर होते हैं और टोकन द्वारा टोकन पढ़ा जाता है:
int a, b;
while (infile >> a >> b)
{
// process pair (a,b)
}
लाइन-आधारित पार्सिंग, स्ट्रिंग धाराओं का उपयोग करते हुए:
#include <sstream>
#include <string>
std::string line;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int a, b;
if (!(iss >> a >> b)) { break; } // error
// process pair (a,b)
}
आपको (1) और (2) का मिश्रण नहीं करना चाहिए, क्योंकि टोकन-आधारित पार्सिंग नईलाइन्स को शोभा नहीं देता है, इसलिए यदि आप getline()
टोकन-आधारित निष्कर्षण के बाद आप का उपयोग करते हैं, तो आप खाली खाली लाइनों के साथ समाप्त हो सकते हैं। पहले से ही लाइन।
int a, b; char c; while ((infile >> a >> c >> b) && (c == ','))
while(getline(f, line)) { }
निर्माण की एक व्याख्या के लिए और त्रुटि से निपटने के संबंध में कृपया इस (मेरे) लेख पर एक नज़र डालें: gehrcke.de/2011/06/… (मुझे लगता है कि मुझे यहाँ बुरा विवेक पोस्ट करने की आवश्यकता नहीं है, यह थोड़ा पूर्व भी है- यह उत्तर)।
ifstream
फ़ाइल से डेटा पढ़ने के लिए उपयोग करें :
std::ifstream input( "filename.ext" );
यदि आपको वास्तव में लाइन द्वारा लाइन पढ़ने की आवश्यकता है, तो यह करें:
for( std::string line; getline( input, line ); )
{
...for each line in input...
}
लेकिन आपको शायद समन्वित जोड़े निकालने की जरूरत है:
int x, y;
input >> x >> y;
अपडेट करें:
अपने कोड में आप का उपयोग ofstream myfile;
, तथापि o
में ofstream
के लिए खड़ा है output
। यदि आप फ़ाइल (इनपुट) के उपयोग से पढ़ना चाहते हैं ifstream
। यदि आप पढ़ना और लिखना दोनों उपयोग करना चाहते हैं fstream
।
C ++ में लाइन द्वारा एक फ़ाइल लाइन पढ़ना कुछ अलग तरीकों से किया जा सकता है।
सबसे सरल तरीका एक std :: ifstream और पाश का उपयोग std :: getline () कॉल को खोलना है। कोड साफ और समझने में आसान है।
#include <fstream>
std::ifstream file(FILENAME);
if (file.is_open()) {
std::string line;
while (std::getline(file, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
file.close();
}
एक और संभावना बूस्ट पुस्तकालय का उपयोग करने के लिए है, लेकिन कोड थोड़ा और अधिक क्रिया हो जाता है। प्रदर्शन ऊपर के कोड के समान है (std के साथ लूप :: getline ())।
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/stream.hpp>
#include <fcntl.h>
namespace io = boost::iostreams;
void readLineByLineBoost() {
int fdr = open(FILENAME, O_RDONLY);
if (fdr >= 0) {
io::file_descriptor_source fdDevice(fdr, io::file_descriptor_flags::close_handle);
io::stream <io::file_descriptor_source> in(fdDevice);
if (fdDevice.is_open()) {
std::string line;
while (std::getline(in, line)) {
// using printf() in all tests for consistency
printf("%s", line.c_str());
}
fdDevice.close();
}
}
}
यदि प्रदर्शन आपके सॉफ़्टवेयर के लिए महत्वपूर्ण है, तो आप C भाषा का उपयोग करने पर विचार कर सकते हैं। यह कोड ऊपर C ++ संस्करणों की तुलना में 4-5 गुना तेज हो सकता है, नीचे बेंचमार्क देखें
FILE* fp = fopen(FILENAME, "r");
if (fp == NULL)
exit(EXIT_FAILURE);
char* line = NULL;
size_t len = 0;
while ((getline(&line, &len, fp)) != -1) {
// using printf() in all tests for consistency
printf("%s", line);
}
fclose(fp);
if (line)
free(line);
मैंने ऊपर दिए गए कोड के साथ कुछ प्रदर्शन बेंचमार्क किए हैं और परिणाम दिलचस्प हैं। मैंने ASCII फ़ाइलों के साथ कोड का परीक्षण किया है जिसमें 100,000 पंक्तियाँ, 1,000,000 पंक्तियाँ और पाठ की 10,000,000 पंक्तियाँ हैं। पाठ की प्रत्येक पंक्ति में औसतन 10 शब्द हैं। कार्यक्रम को -O3
अनुकूलन के साथ संकलित किया गया है और /dev/null
माप से लॉगिंग समय चर को हटाने के लिए इसके आउटपुट को अग्रेषित किया गया है। अंतिम, लेकिन कम से कम, कोड का प्रत्येक टुकड़ा printf()
स्थिरता के लिए फ़ंक्शन के साथ प्रत्येक पंक्ति को लॉग नहीं करता है ।
परिणाम समय (एमएस में) दिखाते हैं कि कोड का प्रत्येक टुकड़ा फाइलों को पढ़ने के लिए लिया गया था।
दो C ++ दृष्टिकोणों के बीच प्रदर्शन अंतर न्यूनतम है और अभ्यास में कोई अंतर नहीं होना चाहिए। C कोड का प्रदर्शन बेंचमार्क को प्रभावशाली बनाता है और गति के मामले में गेम चेंजर हो सकता है।
10K lines 100K lines 1000K lines
Loop with std::getline() 105ms 894ms 9773ms
Boost code 106ms 968ms 9561ms
C code 23ms 243ms 2397ms
std::cout
बनाम के डिफ़ॉल्ट व्यवहार के ज्ञात नुकसान को माप सकते हैं printf
।
printf()
निरंतरता के लिए सभी मामलों में फ़ंक्शन का उपयोग करने के लिए कोड को संपादित किया है । मैंने भी std::cout
सभी मामलों में उपयोग करने की कोशिश की है और इससे कोई फर्क नहीं पड़ा। जैसा कि मैंने अभी पाठ में वर्णन किया है, प्रोग्राम का आउटपुट /dev/null
लाइनों को प्रिंट करने के लिए समय पर मापा जाता है।
cstdio
। आपको सेटिंग के साथ प्रयास करना चाहिए था std::ios_base::sync_with_stdio(false)
। मुझे लगता है कि आपने बहुत बेहतर प्रदर्शन प्राप्त किया होगा (यह गारंटी नहीं है कि जब से इसे लागू किया गया है, जब सिंक्रनाइज़ेशन बंद हो जाता है)।
चूंकि आपके निर्देशांक जोड़े के रूप में एक साथ हैं, तो उनके लिए एक संरचना क्यों नहीं लिखनी चाहिए?
struct CoordinatePair
{
int x;
int y;
};
तो आप istreams के लिए एक अतिभारित निष्कर्षण ऑपरेटर लिख सकते हैं:
std::istream& operator>>(std::istream& is, CoordinatePair& coordinates)
{
is >> coordinates.x >> coordinates.y;
return is;
}
और फिर आप इस तरह एक वेक्टर में सीधे निर्देशांक की एक फ़ाइल पढ़ सकते हैं:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
char filename[] = "coordinates.txt";
std::vector<CoordinatePair> v;
std::ifstream ifs(filename);
if (ifs) {
std::copy(std::istream_iterator<CoordinatePair>(ifs),
std::istream_iterator<CoordinatePair>(),
std::back_inserter(v));
}
else {
std::cerr << "Couldn't open " << filename << " for reading\n";
}
// Now you can work with the contents of v
}
int
धारा में से दो टोकन पढ़ना संभव नहीं होता है operator>>
? कोई इसे एक पीछे वाले पार्सर के साथ कैसे काम कर सकता है (यानी जब operator>>
असफल हो जाता है, तो स्ट्रीम को पिछली स्थिति में वापस लौटाएं वापस झूठे या कुछ और जैसे)?
int
टोकन पढ़ना संभव नहीं है , तो is
धारा का मूल्यांकन होगा false
और रीडिंग लूप उस बिंदु पर समाप्त हो जाएगा। आप operator>>
व्यक्तिगत रीड्स के रिटर्न वैल्यू की जांच करके इसका पता लगा सकते हैं । यदि आप स्ट्रीम वापस करना चाहते हैं, तो आप कॉल करेंगे is.clear()
।
operator>>
इसे और अधिक कहने के लिए सही है is >> std::ws >> coordinates.x >> std::ws >> coordinates.y >> std::ws;
अन्यथा जब से तुम मानते हैं कि अपने इनपुट धारा खाली स्थान के-लंघन मोड में है।
यदि इनपुट है, तो स्वीकृत उत्तर पर विस्तार करना:
1,NYC
2,ABQ
...
आप अभी भी इस तरह से एक ही तर्क को लागू कर पाएंगे:
#include <fstream>
std::ifstream infile("thefile.txt");
if (infile.is_open()) {
int number;
std::string str;
char c;
while (infile >> number >> c >> str && c == ',')
std::cout << number << " " << str << "\n";
}
infile.close();
हालाँकि, फ़ाइल को मैन्युअल रूप से बंद करने की कोई आवश्यकता नहीं है, लेकिन ऐसा करने के लिए फ़ाइल चर का दायरा बड़ा होने पर ऐसा करना अच्छा है:
ifstream infile(szFilePath);
for (string line = ""; getline(infile, line); )
{
//do something with the line
}
if(infile.is_open())
infile.close();
यह उत्तर दृश्य स्टूडियो 2017 के लिए है और यदि आप पाठ फ़ाइल से पढ़ना चाहते हैं, तो कौन सा स्थान आपके संकलित कंसोल एप्लिकेशन के सापेक्ष है।
सबसे पहले अपने टेक्स्ट फ़ोल्डर (इस मामले में test.txt) को अपने समाधान फ़ोल्डर में डालें। कंपाइल करने के बाद ApplicationName.exe के साथ टेक्स्ट फाइल को उसी फोल्डर में रखें
C: \ Users \ "उपयोगकर्ता नाम" \ स्रोत \ रेपोस \ "solutionName" \ "solutionName"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream inFile;
// open the file stream
inFile.open(".\\test.txt");
// check if opening a file failed
if (inFile.fail()) {
cerr << "Error opeing a file" << endl;
inFile.close();
exit(1);
}
string line;
while (getline(inFile, line))
{
cout << line << endl;
}
// close the file stream
inFile.close();
}
यह C ++ प्रोग्राम में डेटा लोड करने का एक सामान्य समाधान है, और रीडलाइन फ़ंक्शन का उपयोग करता है। इसे CSV फ़ाइलों के लिए संशोधित किया जा सकता है, लेकिन सीमांकक यहां एक स्थान है।
int n = 5, p = 2;
int X[n][p];
ifstream myfile;
myfile.open("data.txt");
string line;
string temp = "";
int a = 0; // row index
while (getline(myfile, line)) { //while there is a line
int b = 0; // column index
for (int i = 0; i < line.size(); i++) { // for each character in rowstring
if (!isblank(line[i])) { // if it is not blank, do this
string d(1, line[i]); // convert character to string
temp.append(d); // append the two strings
} else {
X[a][b] = stod(temp); // convert string to double
temp = ""; // reset the capture
b++; // increment b cause we have a new number
}
}
X[a][b] = stod(temp);
temp = "";
a++; // onto next row
}