how can

;fs
Last edited on
When you open the file you start writing to an empty file.
outFile<<Data[modro-1][modcol-1];
This will write the value stored at Data[modro-1][modcol-1] to the file.
So what you get inside the file is actually the old value followed by the new value of Data[modro-1][modcol-1].

What you want is probably to first read the whole 2D array from the file. When you make a change to the 2D array you open the file and write the whole 2D array to the file.
If you don't open a file to read, you probably don't care what is currently in it, so the default behavior when opening a file for output is to truncate it.

ofstream outFile("Data.txt", ios::out | ios::app ) ; or
ofstream outFile("Data.txt", ios::out | ios::ate ) ;

will open the file for output without truncating it. ios::app will cause all data written to the file to be appended. ios::ate will just seek to the end when opening the file.

That said, you do care what is in the file you're opening and you should be reading it.

The usual way to do this is to read in the file, change what you want to change, write the changes out to a new file. Delete the old file, rename the new file. (That way if something causes writing the new file to fail for some reason you still have the old and unchanged data intact in the old file.)
Last edited on
;
Last edited on
I dont want to write to an old file in my assignment it says you have to let the user pick a row and column which they would like to modify.


So your assignment says you do want to write to an old (ie. original) file. Doing as I wrote above is the usual way to do that.

ofstream outFile("Data.txt", ios::out | ios::app ) ; but it just adds the value at the end of last number.


As I said:
ios::ate will just seek to the end when opening the file.
If you don't seek to another place in the file, of course output will be at the end of it.

If you insist on modifying the original file in place, you must:

* know the offset in the file where the value you wish to change is.
* Use seekp() to seek to the appropriate place in the file.
* Write out the value you wish to replace with.

With the caveat that if your output is not exactly the same width as what you're replacing, this is impossible to do in-place. Changing 600 to 4, you may kludge it and write 004, but changing 600 to 1000 would corrupt the format of your file.

http://www.cplusplus.com/reference/iostream/istream/tellg/
http://www.cplusplus.com/reference/iostream/ostream/seekp/

Last edited on
;
Last edited on
See the post above your last if you happened to miss it while composing yours.
;
Last edited on
Using seekp on a text file is not going to work. The best way I can see is to write all elements in Data to the file (using loops).
Last edited on
You must seek to the position in the file where the value you want to replace is. the old value in the array is not the position in the file where the value resides.

The way to do this is to read from the file until you find the place at which the old value resides, seekp() to the same position and output the replacement value.

http://www.cplusplus.com/reference/iostream/istream/tellg/
http://www.cplusplus.com/reference/iostream/ostream/seekp/
Last edited on
;
Last edited on
JohnG wrote:
Is there a way without the seekp


cire wrote:
The usual way to do this is to read in the file, change what you want to change, write the changes out to a new file. Delete the old file, rename the new file. (That way if something causes writing the new file to fail for some reason you still have the old and unchanged data intact in the old file.)


To avoid some complexity (and safety) you could just truncate the old file (I believe you've already discovered how to do that!) after reading everything in, and then write all of the data to the truncated file.
Peter87's assertion that using seekp wouldn't work with a text file prompted me to write some test code, and it does work fine for me. I'm not aware of a reason it wouldn't.

Here's the test. Feel free to use the code if you can integrate it with your own, otherwise it should at least serve as an example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <fstream>
#include <string>
#include <iostream>

const std::fstream::pos_type ErrorValue = -1 ;

std::fstream::pos_type findDataPos(char const* fname, unsigned row, unsigned col)
{
	std::ifstream in( fname) ;
	std::string line ;

	// Rows are delimited by '\n'.  discard rows until we get to the one we're looking for.
	unsigned nRows = 0 ;
	while (nRows < row && std::getline(in, line))
		++nRows ;

	// We'are at the row we want, skip values until we get to the one we want.
	unsigned val ;
	unsigned nCol = 0 ;
	while ( nCol < col && in >> val )
		++nCol ;

	// skip the whitespace before the next value:
	in.get() ;

	// Have any errors occurred so far?
	if ( nCol != col || nRows != row || !in )
		return std::fstream::pos_type(ErrorValue) ;

	return in.tellg() ;
}

bool replaceData( char const* fname, std::fstream::pos_type pos, unsigned value )
{
	// Don't replace data with values that would screw up the file format.
	if (value >= 1000 || pos == ErrorValue)
		return false ;

	std::fstream file(fname) ;
	file.seekp(pos) ;

	// format: 009 091 900
	file.width(3) ;
	file.fill('0');
	file << value ;

	return file.good() ;
}


int main()
{
	// 1, 1 is the logical position of 600 in your file.
	std::fstream::pos_type dataPos = findDataPos("Data.txt", 1, 1) ;

	if ( replaceData("Data.txt", dataPos, 650) )
		std::cout << "Data replacement successful!\n" ;
	else
		std::cout << "Data replacement not successful!\n"
}
;
Last edited on
The way that was originally recommended? Replace the original file (or just truncate it and write the array replacing everything in the file.)
Topic archived. No new replies allowed.