|
BuckBrown wrote: Is your 'if so...' pertaining to the first case or the second case?
Both, actually
After posting I thought about how you were getting those results
and figured you HAD to be using a common stream.
That's not going to work, at least (especially) not in a read and write loop
like you're doing.
There's two pointers each for both the reader and the writer involved here.
One is the stream position, which you have control of.
The other is the reader and writer's internal buffer pointer, which you don't
have control of.
In your first example, first iteration of the loop...
You request to read a line. For efficiency, the reader reads an
entire buffer full (or the entire file, whichever is smaller).
In this case, it looks like the entire file is buffered so the stream pointer
now points to the end of file. All reads come from the readers buffer, all
writes now go to the end of the file, since that's where the stream pointer
was at the point of the first write. I hope that makes sense.
Now let's say you manage to control all of this (using unbuffered I/O and random
access (seeking) to the stream). If you read a string, add a 'X', write it back
to the file, and then try to read the next string, your 'X' will have overwritten the
next string in the file, unless you shift the remaining bytes in the file "to the right"
to make room for the 'X'.
This is why reading and writing each iteration of the loop is not going to work.
You need to do all the reading in one loop, make appropriate changes, then write
the results back to the stream. Sharing the stream like you're doing is fine - just set the
stream position back to the appropriate place before starting the write loop.
Of course, if there's data in the file beyond what you've read, that would all have to be
shifted to make room for anything you add.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks,
How would you go about shifting the data. This would require inserting and deleting characters at a given fileStream->Position and I haven't found any docs on this.
Buck
|
|
|
|
|
To insert bytes in a file, typically something like:
open source file
create/open temp file
read from source file, writing to temp file, until insertion point reached.
write insert data to temp file
read from source file, writing to temp file, until end of source file reached.
close files
delete source file
rename temp file to src file name
That's good for files of unlimited size. For "small" files you may be able to simplify
by doing something like:
read entire stream from just after insertion point to end (into a buffer)
use Stream::SetLength to expand the stream the number of bytes being inserted
write the inserted bytes at the insertion point
write the buffered bytes after the inserted bytes
Maybe there's new stream/file classes that have insertion built in....I've never seen
any though.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks Mark,
I thought I would be able to do this without a temporary file, but that's okay, I will just write it as you have psuedo coded it.
|
|
|
|
|
The second method I described doesn't require a second file (or a separate stream)
but it wouldn't necessarily be good for files GBs in size.
That's why I put "small" in quotes. What's small is relative to your situation, but sometimes
even megabytes could be small enough to just allocate a buffer, read a huge block into
it from a stream, and write it back to the stream at a different location
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi, i'm not sure if i've chosen correct place for my post, but
I'm writing an app in VC++ 2005 EE which is going to display some 3D figures on System::Windows::Forms::Panel^ panel
The problem:
I've written my own class which handles all OpenGL stuff. So all I have to do is:
Create new 3D figure object, and draw it with panel's Paint method.
Constructor needs panel's HWND, so i did something like this:
TFigure *Figure;
Figure = new TCuboid( (HWND)panel->Handle.ToPointer() , panel->Width, panel->Height, 3, 3, 7 );
But this solution doesn't work properly. When i'm trying to initialize OpenGl machine
with this code (inside TCuboid construcor):
m_gHDC = GetDC( hwnd );
SetupPixelFormat();<br />
m_hRC = wglCreateContext( m_gHDC );
the variable: m_hRC is NULL and it shouldn't be.
I've tried my class code with other IDE and all was fine. So i think the problem is with getting panel's HWND.
Can somebody help me please?
-- modified at 9:53 Sunday 14th October, 2007
|
|
|
|
|
Newbie00 wrote: (HWND)panel->Handle.ToPointer()
Shouldn't that be just
panel->Handle
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
No, unfortunately this won't compile:
Error 23 error C2664 : cannot convert parameter 1 from 'System::IntPtr' to 'HWND'
|
|
|
|
|
I left out the cast, sorry. I meant without the ToPointer() call.
I just realized where I use it without the ToPointer(), it's because the
destination is looking for an IntPtr
Anyway, is the HWND non-NULL at that point?
Is GetDC() returning non-NULL?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes GetDC() is returning non-NULL.
|
|
|
|
|
Newbie00 wrote: Yes GetDC() is returning non-NULL
And the HWND you pass to GetDC() is non-NULL too?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
Then I would assume the problem is not related to getting the panel's HWND.
What does GetLastError() return after the failed wglCreateContext call?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yeees :] hmmmmmmmm I've tried to use GetLastError() with FormatMessage() like this:
LPVOID lpMsgBuf;<br />
<br />
FormatMessage( <br />
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,<br />
NULL,<br />
GetLastError(),<br />
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,<br />
0,<br />
NULL <br />
);<br />
<br />
But an exception occures:
An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in Figury.exe
Additional information: Cannot marshal 'parameter #7': Pointers cannot reference marshaled structures. Use ByRef instead.
GetLastError() returns 2000, i don't know what to do :[
|
|
|
|
|
Newbie00 wrote: GetLastError() returns 2000
...which is ERROR_INVALID_PIXEL_FORMAT. Is that a clue?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
how do you know what 2000 means?
That could be a clue, but it's worse than i thought
I have no idea why such strange error occures. I've tried this code with
C++ Builder 6.0 and everything was ok There was no ERROR_INVALID_PIXEL_FORMAT
|
|
|
|
|
There's lots of error codes[^] listed in the documentation for
GetLastError()[^]
I'm not sure what's going on with this, or why it would work with builder.
I guess this leaves SetupPixelFormat() ... what goes on in there?
Is it supposed to have a DC passed to it? If so, is that DC supposed to be a memory DC
or can it be a window DC? Since you can't change the format of a window DC, I would expect
it requires a memory DC - or does it create one internally?
I'm just guessing from what little code I've seen, but I suspect you're passing the wrong DC to
wglCreateContext().
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The old VS had a utility now in 2005 this page[^] says it's in the TOOLS menu.... I don't have it
|
|
|
|
|
Interesting. I don't have that utility either. In fact, I'm pretty sure
I've never found any utilities I wanted to find in VS. Yes, there's ones there
I never use...
*shrug*
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I think i'm passing correct DC.
<br />
void TFigure::SetupPixelFormat()<br />
{<br />
int nPixelFormat = 0;<br />
PIXELFORMATDESCRIPTOR pfd = {<br />
sizeof(PIXELFORMATDESCRIPTOR),<br />
1,<br />
PFD_DRAW_TO_WINDOW |<br />
PFD_SUPPORT_OPENGL |<br />
PFD_DOUBLEBUFFER,<br />
PFD_TYPE_RGBA,<br />
32,<br />
0, 0, 0, 0, 0, 0,<br />
0,<br />
0,<br />
0,<br />
0,0,0,0,<br />
16,<br />
0,<br />
0,<br />
PFD_MAIN_PLANE,<br />
0,<br />
0, 0, 0 };<br />
<br />
nPixelFormat = ChoosePixelFormat( m_gHDC, &pfd );<br />
SetPixelFormat( m_gHDC, nPixelFormat, &pfd );<br />
}<br />
ChoosePixelFormat( m_gHDC, &pfd ); returns 7.
-- modified at 13:35 Monday 15th October, 2007
|
|
|
|
|
STL map = Hashtable, what about STL multimap? Equivalent?
STL Reference[^]
Thanks a bunch.
|
|
|
|
|
There isn't one
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Hi Chris, thanks. Any reason why there isn't an equivalent in .NET ICollection[^]?
I use Hashtable quite often... but I suppose there're application for multimap too...?
|
|
|
|
|
My guess is that the C# team wanted to keep it simple, that appears to be their overall ratonale. I love associative containers, I use them all the time.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
MFC's CMap = HashTable.
STL map = Red-Black Tree.
|
|
|
|
|