0
votes

IN IOS app, module written in C++ I am writing my data (map of basic strings and integers) to a text file. Using following method:

bool Recognizer::saveMap(const char * s)
{
if(trainingData.model && !trainingData.model.empty()) {
    const string filename = string(s);
    std::ofstream file(s, ios_base::trunc );

    try{
        if(! file.is_open())
        {
            file.open(s);
        }
        for (map<String,int>::iterator it=trainingData.idMap.begin(); it!=trainingData.idMap.end(); ++it)
        {
            cout << it->second << " " << it->first << endl;
            file << it->first << endl << it->second << endl;
        }
        file.close();
    }
    catch(cv::Exception & e){
        if(file.is_open())
            file.close();
        int code = e.code;
        string message = e.err;

        cerr << "cv::Exeption code: " << code << " " << message << endl;
        return false;
    }
    std::streampos fileLength = iosFileSize(s);
    cout << "Saved map to: " << filename <<  " length: " << fileLength << endl;
    return true;
}
return false;
}

My contains one entry and console output indicates that two lines: string, string representing number have been written to my file. Subsequent opening file for reading and reading using getline or using stream operator indicates that file is empty:

bool Recognizer::loadMap(const char * s)
{
    std::streampos fileLenght = iosFileSize(s);
    std::ifstream file(s, ios::in);

    try{
        if(file.is_open())
        {           
            string name;
            string lineName;
            string lineTag;
            int tag;
            int count = 0;

            while(getline(file,name))
            {
                if(getline(file,lineTag))
                {
                    tag = stoi(lineTag,0,10);
                    count++;
                    cout << tag << " " << name << endl;
                    trainingData.idMap[name]=tag;
                    trainingData.namesMap[tag]=name;
                }
            }trainingData.personsCount=count;
            file.close();
           }
      }
       catch(cv::Exception & e){
           if(file.is_open())
               file.close();
           int code = e.code;
           string message = e.err;

           cerr << "cv::Exeption code: " << code << " " << message << endl;
           return false;
      }
    cout << "Loaded map from: " << s << " lenght: "<< fileLenght << endl;
    return true;
}

I also copied from one of stackoverflow answers method returning file lenght and using it to verify lenghth of the file after write operation:

std::streampos iosFileSize( const char* filePath ){    
    std::streampos fsize = 0;
    std::ifstream file( filePath, std::ios::binary );
    fsize = file.tellg();
    file.seekg( 0, std::ios::end );
    fsize = file.tellg() - fsize;
    file.close();

    return fsize;
}

The file path passed to saveMap and loadMap seems to be legit. With path that the app could not write to, attempt to write caused exception.

There are no errors returned by write operation but both, attempts to read and iosFileSize() indicate that file is empty. I am not sure if i need call file.open() and file.close() or file is open and closed automatically when output stream is created and later goes out of scope. I experimented with those with the same result ( call to file.is_open returns true so the block calling file.open() is skipped.

What am I doing wrong? I appreciate all responses.

2
And if you look at the file, what is the size of the file? No, not what your program tells you. What your operating system tells you.Sam Varshavchik
I wish I knew how to look at directories on iphone. Is there any console available where I could execute directly unix command like ls -l ?Marek

2 Answers

1
votes

It does not seem like you call file.flush(); anywhere in Recognizer::saveMap() after writing to the file stream. std::ofstream::flush() saves changes you've made to the file. Add file.flush(); between when you make changes to the code and when you close the file. See if that remedies your issue.

-1
votes

I believe from looking at your code that you are overwriting your data when you open the file in the second program you should be using something like this.

std::fstream fs;
  fs.open ("test.txt", ios::app)

instead of doing the ios::in