views:

206

answers:

3

I have a text file looks like this :

100 50 20 90
4.07498 0.074984
37.1704 28.1704
20.3999 14.3999
48.627 35.627 ....

I need to edit this file so that everything is kept the same except the first line, 3rd item. The ouput should look like this:

100 50 19 90
4.07498 0.074984
37.1704 28.1704
20.3999 14.3999
48.627 35.627
....

How can I do it in c++ ? Can anybody help me?

Thanks, Hoang

+2  A: 
#include <stdio.h>

int main()
{
      FILE *pFile;
      pFile = fopen("example.txt", "r+");
      fseek(pFile, 7, SEEK_SET);
      fputs("19", pFile);
      fclose(pFile);
      return 0;
}

Edit: The above was of course mostly a joke. The real way to do it is to read the first line, split it into parts, change the required number, write it out, then follow with all the rest of the lines. If we know that the file contains four integers (floats?) on the first line, something like this might suffice:

#include <fstream>
#include <iostream>
using namespace std;

int main ()
{
    ifstream in("in.txt");
    ofstream out("out.txt");
    float v1, v2, v3, v4;
    in >> v1 >> v2 >> v3 >> v4;
    v3 = 19.1234; // <- Do whatever you need to here.
    out << v1 << " " << v2 << " " << v3 << " " << v4;
    out << in.rdbuf();
    out.close();
    in.close();
    return 0;
}
calmh
Thank you for your solution. But I'm looking for a more "dynamic" way, which means I can change 20 to any number without overwriting the last number. Ex: 20, 19.9999, 19.9998, 17.36...
tsubasa
@tsubasa: Then you should specify that in your question.
Billy ONeal
Added a solution that actually fulfills the extra specifications, and can handle a new number that is longer than the previous one. :)
calmh
This solution is brilliant, exactly what i'm looking for. Thank you very much calmh.
tsubasa
A: 

As long the result is the same length as the original (or shorter, and you don't mind adding spaces to cover the difference) it's pretty easy: seek to where you want to do the modification, write the new data, and you're done:

#include <fstream>
#include <ios>

int main() { 
    std::fstream file("yourfile.txt", std::ios::in | std::ios::out);
    file.seekp(7);
    file << "19";
    return 0;
}

If the data you want to write won't "fit" in between other things you want to preserve, you need to re-write the remainder of the file, typically copying from the old file to a new one, modifying the data as required along the way through.

Edit: something like this:

#include <fstream>
#include <ios>
#include <iterator>
#include <vector>

int main() { 
    std::vector<double> data;

    std::fstream file("yourfile.txt", std::ios::in | std::ios::out);
    std::copy(std::istream_iterator<double>(file), 
        std::istream_iterator<double>(),
        std::back_inserter(data));
    file.clear();
    file.seekp(0);
    data[2] = 19.98;
    std::copy(data.begin(), data.end(), std::ostream_iterator<double>(file, " "));
    return 0;
}

This has a few effects that you may not want -- particularly, as it stands, it destroys whatever "line" oriented structure the original may have had, and simply writes out the result as one long line. If you want to avoid that, you can (for example) read in a line at a time, convert the numbers in the line (e.g. put then into a stringstream, then read them out of there as doubles), modify those, put the result back into a string, and write out the line with a "\n" at the end.

Jerry Coffin
A: 

You can use a std::wfstream.

#include <fstream>

using namespace std;
int main() {
    wfstream file(L"example.txt", std::ios::in | std::ios::out);
    std::wstring first, second, third; // The extraction operator stops on whitespace
    file >> first >> second >> third;
    third = L"Whatever I really, really, want!";
    file << first << second << third;
    file.flush(); // Commit to OS buffers or HDD right away.
}

I've probably screwed up the use of the insertion operator. But, you can reference MSDN for the exactitudes of using the wfstream. I'd absolutely advise against using any C solution, all their string manipulation functions truly suck.

DeadMG