|
The operator LPCTSTR() of CString always points to the 1st character.
If you want to read out sequential 24 character chunks, you will have to use a different mechanism. One suggestion:
char fixBuffer[25]; // note use of 25 to allow for a terminating NULL
int nLength = yourstring.GetLength();
int nStart;
for(nStart = 0;nStart<nLength;nStart+=24)
{
_tcsncpy(fixBuffer,&yourstring[nStart],24);
fixBuffer[24] = 0;
// do something with fixBuffer
}
|
|
|
|
|
That is interesting. I'll try it and back to here if I got any issue.
Thanks again.
I appreciate your help all the time...
Eranga
|
|
|
|
|
Roger Broomfield wrote: _tcsncpy(fixBuffer,&yourstring[nStart],24);
You can't do that with a CString . You have to use (with care) GetBuffer method.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
You are partially correct. I made one mistake in not including the casting to LPCTSTR. YES you can do this in the context I am using because I am ensuring that access is not attempted outside of the boundaries of the CString and object, and that the LPCTSTR operator is used to ensure that the CString object isnt changed during its usage.
char fixBuffer[25]; // note use of 25 to allow for a terminating NULL
int nLength = yourstring.GetLength();
int nStart;
for(nStart = 0;nStart<nLength;nStart+=24)
{
_tcsncpy(fixBuffer,&((LPCTSTR)yourstring)[nStart],24);
fixBuffer[24] = 0;
// do something with fixBuffer
}
|
|
|
|
|
Roger Broomfield wrote: You are partially correct
Oh no, I'm never partially correct!
An hazard of your code: what happens if nLength < 24 ?
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
refer the documentation of _tcsncpy[^] in the remarks section:
The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. If count is greater than the length of strSource, the destination string is padded with null characters up to length count.
So even if yourstring.IsEmpty() is true the code I pasted will work without generating an exception. I used to use it in at least one place, in one of my projects, then I optimized the CString out of the class and replaced it with an array of TCHAR's because the way I was using it was fragmenting memory badly. Usage was that I was creating thousands of instances of the class in a CArray which is contiguous, but the CStrings were allocated and reallocated numerous times in every instance. Also the strings had a maximum length of 16 characters and in release build CString has a minimum AllocationSize of 64 characters.
|
|
|
|
|
_tcsncpy is hazardous developer tolerant .
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Maybe, maybe not. The most common mistake I have seen (and even done myself) is :-
TCHAR strdest[24];
_tcsncpy(strdest,_T("The quick brown fox jumped over the lazy dog"),24);
here I have not allowed for the terminating NULL. So the next time I use strdest as a source it will overflow into the stack, ie:
_tprintf(strdest);
will not display
The quick brown fox jump
there will be random garbage on the end
and worse is if I manually NULL terminate it using the same logic
strdest[24] = 0;
that will probably generate a stack exception on return because I have overwritten the stack.
|
|
|
|
|
Roger Broomfield wrote: Maybe, maybe not.
Don't care about, I was just kidding
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
CPallini wrote: _tcsncpy is hazardous developer tolerant
what about _tcsncpy_s() ?
t
|
|
|
|
|
Eranga Thennakoon wrote: ...after reading the first 24 characters, where the operator LPCTSTR() points to...
_tcsncpy() does not change anything within the CString object. The second argument is the address from which to start copying.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks for all,
Actually I've come across with a new requirement and now my data in a char buffer. I want to read a fixed amount, actually the in to char fixBuffer[24]; , from the larger buffer. Can you give some clue on it.
I appreciate your help all the time...
Eranga
|
|
|
|
|
Hello everyone,
I am using Visual Studio 2005 and I am wondering whether we could debug into the global delete operator?
I have tried to debug by setting a break point to delete statement, but I could only debug into destructor.
My understanding is, when we call delete, the internal operations are,
1. invoking destructor;
2. invoking global delete operator.
Is my understanding correct?
For example,
<br />
class Foo {<br />
<br />
int i;<br />
<br />
public:<br />
<br />
Foo()<br />
{<br />
i = 100;<br />
}<br />
<br />
~Foo()<br />
{<br />
i = 0;<br />
}<br />
};<br />
<br />
int main (int argc, char** argv)<br />
{<br />
Foo* f = new Foo();<br />
<br />
delete f;
<br />
return 0;<br />
}<br />
thanks in advance,
George
|
|
|
|
|
why don't you just place a break point in the destructor of the object?
|
|
|
|
|
Thanks Haroon,
I can debug into the destructor, but can not debug into global delete operator.
regards,
George
|
|
|
|
|
hmmm...actually its debugging into it fine on my end (in VS2003)...
|
|
|
|
|
Hi Haroon,
You mean you can debug into the global delete operator in Visual Studio 2003 from delete <pointer> statement? I am using Visual Studio 2005.
regards,
George
|
|
|
|
|
It's a little more complex than that, at least in a Debug build which is where you'll most likely be debugging. In order to debug into delete properly you need to have installed the CRuntime Source files when you installed Visual Studio ( They can probably be added afterwards form the CD ) and then you need to include their folder in the source paths for your project so the debugger can find the source.
delete is potentially a long and complex process depending on what you're deleting and even with all the source not every stage will be visible. Remember the compiler generates destructors for classes where you don't write one and these will get called but throw you into the disassembler because there is no source just injected machine language. Don't let this put you off.
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
Thanks Matthew,
Through my study, I find the global delete operator is defined in dbgdel.cpp, and I have the source codes. I have tried to add it to the source folders by Source Files --> Add --> Existing Item, but in this approach, it will bring me more and more dependencies' error (e.g. can not find .h or something) when I build all the files (including deldbg.cpp) in my project. So I think it may be not the correct way to add the source to my project. Could you help to indicate in my situation what is the most appropriate way to add the source to my project please?
regards,
George
|
|
|
|
|
I am trying to write event macros for excel in vb editor but it works when the excel is open but when i close and reopen the excel it does not work. can any one let me know what wrong i am doing in excel
S.Yamini
|
|
|
|
|
Where's the C++ question?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br />
Peter Weyzen<br />
Staff Engineer<br />
<A HREF="http://www.soonr.com">SoonR Inc -- PC Power delivered to your phone</A>
|
|
|
|
|
Hi, I'm wondering which of these is more efficient in C code:
Let's say I have a function:
int check(int x)<br />
{<br />
int var;<br />
<br />
var = calc_var(x);<br />
<br />
return var;<br />
}
Is it more efficient to make that "int var;" into "static int var;" or is it better to keep it as non-static? This is a single-threaded program and the "calc_var" function always returns a value so changing var to static will have exactly the same programmatic behavior, I'm just wondering which is actually a more efficient way to do it, since this "check(int x)" function is called all over the place constantly, sometimes hundreds of times per second.
Thanks!
KR
|
|
|
|
|
In my humble opinion negligible change in efficiency. The way to get more efficient code in that case is to do this
__inline int check(int x) { return calc_var(x); }
provided the compiler complies with the __inline hint it will remove "sometimes hundreds of times per second" of constructing and releasing a stackframe around the unnecessary function call.
Or even, at the risk of incurring the wrath of some of the other members here
#define check(x) calc_var(x)
which will guarantee the unnecessary function call and stackframe are eliminated
|
|
|
|
|
int check(int x)
{
return calc_var(x);
}
would be better as the int is only copied once. If you need the value of calc_var() for further processing in check() I'd avoid a static as you will probably end up confusing the optimiser and wind up with worse machine code. In my limited experiance spending time on questions like this is often a waste of time.
|
|
|
|
|
Sorry, I was sort of unclear with my question; the check function I posted is a simplistic example, the real function is about 600 lines long and is a lot more complex than just returning another function, so it's not as easy as just eliminating a variable declaration.
KR
|
|
|
|