अद्यतन: @Jettatura देखें मुझे लगता है कि यह सबसे अच्छा जवाब https://stackoverflow.com/a/33612982/225186 (केवल लिनक्स?) है।
मूल:
(शायद नहीं पार मंच है, लेकिन सरल)
http://www.ginac.de/~kreckel/fileno/ (ड्वोरक जवाब) में हैक Simplifiying, और इस जीसीसी विस्तार http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00069.html#a59f78806603c619eafcd4537c920f859 को देख, मैं इस समाधान है कि काम करता है GCC
(4.8 कम से कम) और clang
(3.3 कम से कम)
#include<fstream>
#include<ext/stdio_filebuf.h>
typedef std::basic_ofstream<char>::__filebuf_type buffer_t;
typedef __gnu_cxx::stdio_filebuf<char> io_buffer_t;
FILE* cfile_impl(buffer_t* const fb){
return (static_cast<io_buffer_t* const>(fb))->file(); //type std::__c_file
}
FILE* cfile(std::ofstream const& ofs){return cfile_impl(ofs.rdbuf());}
FILE* cfile(std::ifstream const& ifs){return cfile_impl(ifs.rdbuf());}
और सीए पर n इस प्रयोग की जाने वाली,
int main(){
std::ofstream ofs("file.txt");
fprintf(cfile(ofs), "sample1");
fflush(cfile(ofs)); // ofs << std::flush; doesn't help
ofs << "sample2\n";
}
सीमाएं: (टिप्पणियों स्वागत कर रहे हैं)
मैं लगता है कि यह std::ofstream
को fprintf
मुद्रण के बाद fflush
के लिए महत्वपूर्ण है, अन्यथा "sample2" पहले दिखाई देने वाला " नमूना 1 "उपर्युक्त उदाहरण में। मुझे नहीं पता कि fflush
का उपयोग करने के लिए इसके लिए बेहतर कामकाज है या नहीं। विशेष रूप से ofs << flush
मदद नहीं करता है।
फ़ाइल को निकाला नहीं जा सकता * std::stringstream
से, मुझे यह भी पता नहीं है कि यह संभव है या नहीं। (एक अद्यतन के लिए नीचे देखें)।
मैं अभी भी कैसे निकालने के लिए पता नहीं है सी stderr
std::cerr
आदि से, उदाहरण के fprintf(stderr, "sample")
में उपयोग करने के लिए, इस fprintf(cfile(std::cerr), "sample")
की तरह एक काल्पनिक कोड में।
FILE* cfile(std::ostream const& os){
if(std::ofstream const* ofsP = dynamic_cast<std::ofstream const*>(&os)) return cfile(*ofsP);
if(&os == &std::cerr) return stderr;
if(&os == &std::cout) return stdout;
if(&os == &std::clog) return stderr;
if(dynamic_cast<std::ostringstream const*>(&os) != 0){
throw std::runtime_error("don't know cannot extract FILE pointer from std::ostringstream");
}
return 0; // stream not recognized
}
FILE* cfile(std::istream const& is){
if(std::ifstream const* ifsP = dynamic_cast<std::ifstream const*>(&is)) return cfile(*ifsP);
if(&is == &std::cin) return stdin;
if(dynamic_cast<std::ostringstream const*>(&is) != 0){
throw std::runtime_error("don't know how to extract FILE pointer from std::istringstream");
}
return 0; // stream not recognized
}
प्रयास iostringstream
यह का उपयोग कर istream
से fscanf
के साथ पढ़ने के लिए संभव है संभाल करने के लिए:
पिछले सीमा के बारे में, केवल वैकल्पिक हल मैंने पाया इन भार के जोड़ने के लिए है fmemopen
, लेकिन प्रत्येक पढ़ने के बाद स्ट्रीम की इनपुट स्थिति को रखने और अपडेट करने की बहुत सारी किताब की आवश्यकता होती है, अगर कोई सी-रे को जोड़ना चाहता है विज्ञापन और सी ++ - पढ़ता है। मैं इसे उपरोक्त की तरह cfile
फ़ंक्शन में परिवर्तित करने में सक्षम नहीं था। (शायद cfile
वर्ग जो प्रत्येक पढ़ने के बाद अद्यतन करता रहता है वह रास्ता है)।
// hack to access the protected member of istreambuf that know the current position
char* access_gptr(std::basic_streambuf<char, std::char_traits<char>>& bs){
struct access_class : std::basic_streambuf<char, std::char_traits<char>>{
char* access_gptr() const{return this->gptr();}
};
return ((access_class*)(&bs))->access_gptr();
}
int main(){
std::istringstream iss("11 22 33");
// read the C++ way
int j1; iss >> j1;
std::cout << j1 << std::endl;
// read the C way
float j2;
char* buf = access_gptr(*iss.rdbuf()); // get current position
size_t buf_size = iss.rdbuf()->in_avail(); // get remaining characters
FILE* file = fmemopen(buf, buf_size, "r"); // open buffer memory as FILE*
fscanf(file, "%f", &j2); // finally!
iss.rdbuf()->pubseekoff(ftell(file), iss.cur, iss.in); // update input stream position from current FILE position.
std::cout << "j2 = " << j2 << std::endl;
// read again the C++ way
int j3; iss >> j3;
std::cout << "j3 = " << j3 << std::endl;
}
बहुत बुरा यह केवल बीएसडी के लिए है; यह एक अच्छा समाधान होगा क्योंकि यह किसी भी प्रकार की सी ++ स्ट्रीम के साथ एक फ़ाइल * का उपयोग करने की अनुमति देगा। –
आपने पूछा "क्यों?": क्योंकि किसी के पास सी में लिखे गए प्रिंट का सी कार्यान्वयन हो सकता है, जिसे सी ++ ओस्ट्रीम (या ऑफस्ट्रीम) के लिए पुन: उपयोग करना पड़ सकता है। – alfC
क्यों? क्योंकि ऑपरेटर को ओवरलोड करना << बहुत आसान है जब मैं * ऑब्जेक्ट का उपयोग कर रहा हूं, लेकिन स्वरूपण स्ट्रीम आउटपुट गन्दा और दर्दनाक हो सकता है। Fprintf() के साथ स्वरूपण कॉम्पैक्ट और आसान है। दूसरे शब्दों में, मैं 'out << someObject << anotherObject' लिखने में सक्षम होना चाहता हूं लेकिन ऑपरेटर लागू कर सकता हूं << 'fprintf (ofp,"% 8.1lf% 2d \ n ", doubleVar, intVar) का उपयोग करके' – riderBill