|
Christian Graus wrote:
::strcpy(&str[i], &str[i+1]);
That will probably work, but depends on the compiler implementation. From the remarks on strcpy documentation[^]:
"The behavior of strcpy is undefined if the source and destination strings overlap."
Here's an alternative, which doesn't use strcpy , and in which each character is copied only once. How and why this works is left as an exercise to the original poster.
size_t strip_white(_TCHAR* str)
{
_TCHAR* p = str;
_TCHAR* q = str;
while (*q)
{
if (::_istspace(*q))
q++;
else
{
if (p != q)
*p = *q;
p++; q++;
}
}
*p = '\0';
return p - str;
}
--
jlr
http://jlamas.blogspot.com/[^]
|
|
|
|
|
I started with something like this, then decided it was bloat, easily replaced by strcpy. I guess I should have looked a little closer. Is memcpy the same ?
|
|
|
|
|
Christian Graus wrote:
I started with something like this, then decided it was bloat, easily replaced by strcpy. I guess I should have looked a little closer. Is memcpy the same ?
Yes, memcpy is also undefined for overlapping buffers. You could use memmove , though, which does support overlaps.
However, an additional problem in that solution is one of efficiency. Since for each space found you copy the remainder string, many characters are copied multiple times. In you example, which used " This is a test of the veracity of my system..... " as input, which is a short 50 bytes string, the following substrings were copied:
"This is a test of the veracity of my system..... " = 49 bytes
"is a test of the veracity of my system..... " = 44 bytes
"a test of the veracity of my system..... " = 41 bytes
"test of the veracity of my system..... " = 39 bytes
"of the veracity of my system..... " = 34 bytes
"the veracity of my system..... " = 31 bytes
"veracity of my system..... " = 27 bytes
"of my system..... " = 18 bytes
"my system..... " = 15 bytes
"system..... " = 12 bytes
In total, 310 characters were copied. In the alternative solution, each character of the final result was copied only once, that is, only 39 single-byte copy operations were performed. 310 is almost 8 times 39, and to make things worse, the proportion will grow exponentially for larger strings. For example, if we used as input the same string concatenated to the original one (a 100 bytes string), one algorithm would perform 78 byte copy operations, while the other would do 1120, which is more than 14 times larger. If we used as input three times the original string (150 bytes), the numbers would then be 117 bytes copied in one algorithm against 2430 in the other, which is more than 20 times larger!
Using while (*q) instead of the strlen + for combination is an additional optimization, because you don't need to traverse the whole [potentially long] string just to find out its length. Using while , all the processing can be done in a single pass.
--
jlr
http://jlamas.blogspot.com/[^]
|
|
|
|
|
Hi guys ,
i have next question :
what will the output be of this program?
...
char* foo()
{
char *c = "this is a test";
return c;
}
char* foo1()
{
char c[] = "this is a test";
return c;
}
int _tmain(int argc, _TCHAR* argv[])
{
...
char p1 = foo1();
char p = foo();
cout<<p1<<endl;
cout<<p;
return 0;
...
}
i dont get it. i thought that the output of foo() and foo1() had to be the same . more exactly foo1() had to print some strange symbols as the memory allocated for c[] would be freed after this funcion ended. but why does not the sane happen with c* in foo()?
what am i getting wrong??
"Success is the ability to go from one failure to another with no loss of enthusiasm." - W.Churchill
-- modified at 17:48 Thursday 22nd September, 2005
|
|
|
|
|
Giorgi Moniava wrote:
char c[] = "this is a test";
Because it's an array, this memory is allocated in to context of the function, and lost when you return.
Giorgi Moniava wrote:
char *c = "this is a test";
Because it's a pointer, this memory is not freed, and so is a leak, unless the caller deletes it.
In both cases, you'd do better to return std::string. ( Yes, I realise this is an experiment, but that's the lesson to learn from it )
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Christian Graus wrote:
Because it's a pointer, this memory is not freed, and so is a leak, unless the caller deletes it.
Nom you don't have to (and you shouldn't) delete this memory, otherwise you will get an assertion. This memory has not been dynamically allocated so it shouldn't be deleted by the user. The two cases are the same. No memory has been dynamically allocated so everything will be freed at the end of the function.
Christian Graus wrote:
In both cases, you'd do better to return std::string
So true
|
|
|
|
|
Both returned adresses point to memory that has been freed. So you cannot predict what will be the contents of these adresses. Maybe it is still good (if nothing erased it), maybe it is totally wrong. In your case, if the contents of p are still good and not those of p1, it's probably due to the fact that after calling foo(), you don't allocate extra memory. As a test, you could just reverse the calls of the function and check the results:
char p = foo(); <br />
char p1 = foo1();
|
|
|
|
|
char *c="This is a test"
here c points to the constant string "This is a test" which, presumably, resides somewhere in the constant or text section of the executable image. This pointer will always be valid independent of scope. Of course, it's bad programming practise that will easily give you problems, but c actually points to valid memory upon return from foo(), and this memory will never be freed (and won't have to be).
Of course, it's a totally different situation with char c[]="This is a test" . Here a copy of the constant string is made, and the copy (c[]) goes out of scope, is freed (well, the stack space is reclaimed) and lost in cyberspace. That's why foo1() doesn't work.
I wonder what would happen if c[] was declared const? Would the compiler make an actual copy or just let c point to the constant string "This is a test"? Since c is declared to point to constant memory I can easily imagine that the optimiser would do this.
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Steen Krogsgaard wrote:
I wonder what would happen if c[] was declared const? Would the compiler make an actual copy or just let c point to the constant string "This is a test"? Since c is declared to point to constant memory I can easily imagine that the optimiser would do this.
Hi Steen,
thanks for reply,
the same is happening when i declare c[] as a const
"Success is the ability to go from one failure to another with no loss of enthusiasm." - W.Churchill
|
|
|
|
|
So, apparently the compiler still makes a copy. Anyway it's not significant, the point is that your pointer version is valid (but bad design in my mind) and the array version is not. The reason for this is as I have described previously.
Just out of curiosity, did you try the const-array version in both debug and release mode? I would guess that in debug you would still see problems, but in release mode it might work. But it's still a bad idea
Cheers
Steen.
"To claim that computer games influence children is ridiculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Yes Steen i agree that it is bad design , i was just experimenting.
Steen Krogsgaard wrote:
Just out of curiosity, did you try the const-array version in both debug and release mode? I would guess that in debug you would still see problems, but in release mode it might work. But it's still a bad idea
Yep , and the result is the same in both Debug and Release Builds
"Success is the ability to go from one failure to another with no loss of enthusiasm." - W.Churchill
|
|
|
|
|
cedric moonen wrote:
Both returned adresses point to memory that has been freed.
I also knew this and thats why i expected that the output of foo() and foo1() had to be the same.
cedric moonen wrote:
As a test, you could just reverse the calls of the function and check the results:
i've done it already but result is the same.
"Success is the ability to go from one failure to another with no loss of enthusiasm." - W.Churchill
|
|
|
|
|
how many times are you going to ask the same question ?
Yesterday[^], DavidCrow And Nishant Sivakumar already gave you some efficient enough answers...
what are you looking for man ?
TOXCCT >>> GEII power [toxcct][VisualCalc]
-- modified at 4:27 Friday 23rd September, 2005
|
|
|
|
|
toxcct wrote:
how many times are you going to ask the same question ?
Yesterday[^], DavidCrow And Nishant Sivakumar already gave you some efficient enough answers...
what are you looking for man ?
Loo well at the question i asked yesterday and at this question .
I'm sure you will find difference
"Success is the ability to go from one failure to another with no loss of enthusiasm." - W.Churchill
|
|
|
|
|
yep, you're right, i'm not well woken up this morning... sorry
TOXCCT >>> GEII power [toxcct][VisualCalc]
|
|
|
|
|
no problem
"Success is the ability to go from one failure to another with no loss of enthusiasm." - W.Churchill
|
|
|
|
|
hello,
today i tried to create a program- a new project. i tried with Managed C++, Windows Form Application (.NET), i even checked on Delphi. but, at the end, i found out MFC is really the best solution for a project i would create since i worked in MFC before.
i would really like to know if there is an option to get Windows Form Application controls working in mfc.
For example:
i would like to add to my application imagelist, then i would like to add 32bit ico and png files into it. the main reason is actually, that the default MFC support only 256 colors - BMP images and lowcolored ICO files. but i really want for my program to look as good as possible!
any ideas how to do that? thanks for all the info guys and gals
|
|
|
|
|
lordgreg wrote:
i would like to add to my application imagelist, then i would like to add 32bit ico and png files into it.
Google will give you heaps of hits on solutions to this problem. I don't recall what they are, but I was doing this with help from the web 6 years ago.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
hi
can any one tell me that how can i send message from a thread to the dll main, actually i thread is within the dll, now there is a need to display the message that stop the thread for a moment asking the user request to continue or not, now i want this message to be displayed from the dll and not from the thread (i.e outside the thread), i studied about send message and postmessages, but what actually should i do ,, i shall be thankful
for ur help
thanks
|
|
|
|
|
This is my understanading of the problem...
1. You have an application and a dll
2. You are creating a thread which thread proc is in the DLL function
3. You need to send a message to the Thread which reside insode the dll..
Am I right?
PostMessage and SendMessage are used to send or post a message to the same proc.. Obviously they are belongs to the Window and processed by the Window Proc. As you know Window and Thread are fundamentally different..
In your case, your have two threads (minimum, one is your application thread and another one is dll thread...
For sending messages between the threads you have to use PostThreadMessage() function. For that you need the thread id of the destination.
Hope this help you.. Let me know if you need more information...
" Action without vision is only passing time,
Vision without action is merely day dreaming,
But vision with action can change the world "
- Words from Nelson Mandela
Thanks & Regards,
Gopalakrishnan
|
|
|
|
|
I am getting a compilation error using strings...
I believe I need to convert a char* to a TCHAR?
char* str;
str = "test";
TCHAR pzFolder[1] = TEXT(str); // fails here with error C2440: 'initializing' : cannot convert from 'char *' to 'char [261]'
|
|
|
|
|
pzFolder is an array of chars. str is a char pointer. You need to use _tcscpy(pzFolder, str); (And pzFolder needs to be longer than 1 char.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
I am trying to convert a time string to hexidecimal format with a fixed length of 4 bytes. When I do the conversion below I get 7D5 when what I want is 07D5. Is there an easy way to pad the left hand side of the string with zeros? I also need to do this with seconds where I will have to pad more than 1 zero. I know I can do some string length checks and add zeros but I think there is an easier way out there.
Thanks,
Ryan
SYSTEMTIME st;
short year;
GetSystemTime(&st);
year = st.wYear;
CString Trialtime;
Trialtime.Format("%X", year);
|
|
|
|
|
Ryan Riel wrote:
Is there an easy way to pad the left hand side of the string with zeros?
Sure.
Trialtime.Format("%04X", year);
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
|
|
|
|
|
Thanks,
I tried just ("%4X", year) but that didn't do it. Now I know.
Thanks again
Ryan
|
|
|
|