2015-03-12 12 views
7

पर खुलता नहीं है मैं आउटपुट के लिए एक फ़ाइल खोलने और इसमें शामिल करने की कोशिश कर रहा हूं। इसमें शामिल होने के बाद, मैं फ़ाइल में कहीं और अपनी आउटपुट स्थिति को स्थानांतरित करना चाहता हूं और मौजूदा डेटा को ओवरराइट करना चाहता हूं। जैसा कि मैं इसे समझता हूं, std::ios_base::appबल सभी फाइल के अंत में नहीं है जो मैं करना चाहता हूं। इस प्रकार, मेरा मानना ​​है कि std::ios_base::atestd::ofstream::open() पर जाने के लिए सही ध्वज है। हालांकि, यह काम नहीं कर रहा हो जाने की उम्मीद के रूप में लगता है:std :: std :: ateream के साथ अंत में

// g++ test.cpp 
// clang++ test.cpp 
// with and without -std=c++11 
#include <iostream> 
#include <fstream> 

int main() { 
    std::streampos fin, at; 
    { 
     std::ofstream initial; 
     initial.open("test", std::ios_base::out | std::ios_base::binary); 
     if (not initial.good()) { 
      std::cerr << "initial bad open" << std::endl; 
      return 1; 
     } 
     int b = 100; 
     initial.write((char*)&b, sizeof(b)); 
     initial.flush(); 
     if (not initial.good()) { 
      std::cerr << "initial write bad" << std::endl; 
      return 1; 
     } 
     fin = initial.tellp(); 
    } 
    { 
     std::ofstream check; 
     check.open("test", std::ios_base::out | std::ios_base::binary | std::ios_base::ate); 
     if (not check.good()) { 
      std::cerr << "check bad open" << std::endl; 
      return 1; 
     } 
     at = check.tellp(); 
     if (fin != at) { 
      std::cerr << "opened at wrong position!\nfin:\t" << fin << "\n" << "at:\t" << at << std::endl; 
      return 1; 
     } 
     int bb = 200; 
     check.write((char*)&bb, sizeof(bb)); 
     check.flush(); 
     if (not check.good()) { 
      std::cerr << "check write bad" << std::endl; 
      return 1; 
     } 
     at = check.tellp(); 
    } 
    if ((fin + std::streampos(sizeof(int))) != at) { 
     std::cerr << "overwrite?\nfin:\t" << fin << "\n" << "at:\t" << at << std::endl; 
     return 1; 
    } 
    return 0; 
} 

विशेष रूप से, यह है कि std::ios_base::ateनहीं कदम उदाहरण ऊपर देखा के साथ अंत करने के लिए प्रारंभिक उत्पादन सूचक करता है लगता है। जाहिर है, इसका परिणाम फ़ाइल की शुरुआत को ओवरराइट करने वाला पहला लिखना होगा (जो मेरी परेशानी का कारण बनता है)।

ऐसा लगता है या तो कार्यान्वयन सही नहीं है कि वरना cplusplus.com गलत है ("आउटपुट स्थिति फ़ाइल के अंत में शुरू होता है।") और cppreference.com अस्पष्ट है ("धारा के अंत करने के लिए तुरंत खुल जाएं तलाश ": कौन सी स्ट्रीम?)।

स्पष्ट रूप से एक आसान कामकाज है: बस stream.seekp(0, std::ios_base::end) का उपयोग करें।

तो मेरा प्रश्न इस प्रकार है: क्या मेरा कोड गलत है? क्या कार्यान्वयन गलत है? क्या संदर्भ साइट गलत हैं? किसी भी जानकारी की सराहना की जाएगी।

+2

http://en.cppreference.com/w/cpp/io/ छोटा किया जा सकता basic_filebuf/खुला। 'ऐप' या 'इन' ट्रंकेट्स के बिना 'आउट' का उपयोग करना। –

उत्तर

7

आप में N4296 [filebuf.members]

file io

संयोजन निम्नलिखित चार्ट से देख सकते हैं binary | out"wb" की stdio बराबर में फ़ाइल, खुल जाएगा जो truncate to zero length or create binary file for writing होगा (N1570 7.21.5.2)।

के रूप में counterintuitive के रूप में यह एक ofstream के लिए लगता है, आप in फ्लैग जोड़ने के लिए यदि आप अपनी फ़ाइल नहीं करना चाहती आवश्यकता होगी कटा हुआ, या app यदि आप काट-छांट से बचने और पर फ़ाइल के अंत में तलाश करना चाहते हैं प्रत्येक लिखते हैं।

बोनस टिप: fstream, ifstream और ofstream विपरीत स्वचालित रूप से या std::ios_base::in और किसी भी झंडे आप निर्माता करने के लिए या open दी जाने वाली क्रमशः std::ios_base::out। तुम भी झंडे का उपयोग करने की वस्तु ही उपयोग कर सकते हैं:

std::ofstream check("test", check.in | check.binary | check.ate); 

good के लिए जांच भी करने के लिए if (!initial) आदि

+2

ओह डेरप। वह * पूरी तरह से * समझ में आता है ... ट्रंकेट के लिए एक विशिष्ट फ्लैट होने पर इनपुट ध्वज का उपयोग नहीं किया जाता है। वहां कुल ज्ञान है। हालांकि यह मुद्दा था। धन्यवाद :) – inetknght

संबंधित मुद्दे