|
I'm looking for C++ code that compress Null-terminated string to minimum bytes.
The string has between 1 and 50 characters.
Thanks in advance
Didi
|
|
|
|
|
If it's only for 1 to 50 characters why compress...?
Anyways...each character uses 1 byte...but normal english requires only decimal 33 to 126 ascii.
126 - 33 = 93...which is not even close to 255, the maximum value that can fit into one byte.
11111111=255
01111111=127
00111111=63, no good!
from the above you can see that by using only the ascii characters in this range you can knock off one bit on each character, 8 characters later...thats one byte saved.
If you don't need case and some of the funny characters you could further shave off another bit, saving even more memory.
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Thanx HockeyDude,
I forgot to say that the string has uppercase letters only and no special characters except underscore. (f.e MY_NAME_IS_DD)
do you have any idea when I can find C++ code that imlements what you described ?
Thanx
DD
|
|
|
|
|
I don't actually, but it sounds like a interesting project to undertake when time permits.
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
What is wrong with this?
CPaintDC dc(this);
Graphics graphics(dc.m_hDC);
Bitmap* bitmap;
bitmap = Bitmap::FromResource(AfxGetApp()->m_hInstance, L"IDB_BITMAP1");
CachedBitmap cachedBitmap(bitmap, &graphics);
graphics.DrawCachedBitmap(&cachedBitmap, 10, 10);
I get nothing painted at all? I get no errors from the compiler at all either.
|
|
|
|
|
bitmap = Bitmap::FromResource(AfxGetApp()->m_hInstance, MAKEINTRESOURCEW(IDB_BITMAP1));
|
|
|
|
|
Thanks Alex! That worked, although I still don't quite understand why it works.
|
|
|
|
|
Never mind, It's always the simple and obvious things that get me. It makes perfectly good sense to me now. The Documentation states:
Pointer to a null-terminated string that specifies the path name of the bitmap resource to be loaded. Alternatively, this parameter can consist of the resource identifier in the low-order word and zero in the high-order word. You can use the MAKEINTRESOURCE macro to create this value.
Thanks Alex.
|
|
|
|
|
Hello -- i am reading a list of values and need to convert certain strings to integers.
For example I have used the val() function in visual basic for this purpose. is there an equivalent in c++. (i know atoi works for type const char*, but what about the STL string)
thanks,
tim
p.s. in my code i have (where this is a relative date type in the form DHHMM) I need to modify the middle two values and then store the total as an int
61559
61600
61601
61602
61603
61604
61605
61606
---------------------------------------
Tim Booher
|
|
|
|
|
there is:
<br />
long atol(char* str)<br />
It will search through a character string until it reaches a character that is not a number and return the result as a long value.
|
|
|
|
|
atoi() or atol()
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
yeah -- but these aren't overloaded for the STL string -- i am getting conversion errors :<
tim
---------------------------------------
Tim Booher
|
|
|
|
|
use the c_str() function on your object and you will get a const char* to pass into these functions.
|
|
|
|
|
try:
int n = atoi(str.c_str());
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
sweet -- that works great i have:
string convertToMilitary(const string& strTime)
{
// input of form DHHMM i.e. 40112 = 4th day 1:12 pm
string strConverted = "";
int intHour = 0;
intHour = atoi(strTime.substr(1,2).c_str());
if (intHour < 9) intHour += 12;// what is the diff from +=
strConverted = strTime.replace(1,2,intHour);
// output of form DHHMM military (41312)
return strConverted;
}
now i just need to put them back together with all the zeros intact . . . I know i need to change intHour back to string with mask "00"
laters,
tim
---------------------------------------
Tim Booher
|
|
|
|
|
Hello everyone, I'm desperate.
What is going on with this. In debug mode it behaves correctly,
giving the correct output showing the insertions made into the
string:
C:\PleaseHelpMe>cd debug
C:\PleaseHelpMe\Debug>pleasehelpme
~@~bt~@~ <title>The Title of the Document ~@~et~@~ </title>
C:\PleaseHelpMe\Debug>pleasehelpme
~@~bt~@~ <title>The Title of the Document ~@~et~@~ </title>
But in release mode, nothing happens! No changes are made
to the string. Please help!
C:\PleaseHelpMe\Debug>cd ..
C:\PleaseHelpMe>cd release
C:\PleaseHelpMe\Release>pleasehelpme
<title>The Title of the Document </title>
What is going on? Please help I'm so confused!
Thank you
-Julie
// PleaseHelpMe.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <afx.h>
static TCHAR g_szBeginTitle[] = "~@~bt~@~";
static TCHAR g_szEndTitle[] = "~@~et~@~";
void InsertCode( TCHAR*& pszBuffer, TCHAR* pszKeyWord, bool& bLineChanged )
{
if ( pszBuffer )
{
*pszBuffer = ' ';
pszBuffer++;
while (*pszBuffer != '\0' && *pszKeyWord != '\0' )
{
*pszBuffer = *pszKeyWord;
pszBuffer++;
pszKeyWord++;
}
if ( pszBuffer )
{
*pszBuffer = ' ';
pszBuffer++;
}
bLineChanged = true;
}
}
void MarkHTMLSignificance( CString& strLine )
{
CString strNewLine;
int nLen = strLine.GetLength() + 2;
TCHAR* pszSource = strLine.GetBuffer( nLen );
TCHAR* pszResult = strNewLine.GetBuffer( nLen * 8 );
bool bLineChanged = false;
while (*pszSource != '\0')
{
if ( *pszSource == '<' )
{
LPTSTR pszTest = pszSource + 1;
switch ( *pszTest )
{
case 't': // possibly title
case 'T':
if ( _tcsnicmp( pszTest, _T("title"), 5 ) == 0 )
InsertCode( pszResult, g_szBeginTitle, bLineChanged );
break;
case '/':
pszTest++;
switch( *pszTest )
{
case 't':
case 'T':
if ( _tcsnicmp( pszTest, _T("title"), 5 ) == 0 )
InsertCode( pszResult, g_szEndTitle, bLineChanged );
break;
} // end switch on slash
} // end switch on t, h, b, slash
} // end if < found
*pszResult = *pszSource;
pszSource++;
pszResult++;
} // end while *pszSource != '\0'
*pszResult = *pszSource; // null terminate!!!
strLine.ReleaseBuffer();
strNewLine.ReleaseBuffer();
if ( bLineChanged )
strLine = strNewLine;
}
int main(int argc, char* argv[])
{
CString strHTML = " <title>The Title of the Document</title> \n";
MarkHTMLSignificance( strHTML );
printf( strHTML );
return 0;
}
|
|
|
|
|
Please, when you post code that has < and > characters in it, either manually replace them with < and >, use a program that will do it for you, or check the Display this message as-is (no HTML) checkbox when posting. It's very hard to read otherwise. Using the <pre> tag around your code (for indentation) would also be nice.
Ok, here's one problem:
void MarkHTMLSignificance( CString& strLine )
{
...
TCHAR* pszResult = strNewLine.GetBuffer( nLen * 8 );
...
InsertCode( pszResult, g_szBeginTitle, bLineChanged );
...
}
void InsertCode( TCHAR*& pszBuffer, TCHAR* pszKeyWord, bool& bLineChanged )
{
...
while (*pszBuffer != '\0' && *pszKeyWord != '\0' )
...
}
A buffer is allocated, but no initialization other than copying in the original string is performed. Looking for a NULL terminator is not a good idea; you should instead pass in a length count, and check using that.
I should also probably mention the CString::Replace() method...
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
Okay, I fixed the display of the message... thanks
But see, I don't to replace anything, I just want to insert
some characters at a specified place. And I want to go fast, cause
I have to process a lot of text, so that's why I'm trying to use
pointers instead of CString operations. And it works fine in debug
mode, that is what is killing me.
I even tried turning off all release mode optimizations, and still
nothing!
Even if I set strNewLine to "", that does not make any difference.
Its like the release mode version doesn't like the fact that I'm
passing a TCHAR* by reference to InsertCode. But why?
Sigh... I was hoping to have this program done by Monday, but
its not looking good because of this... :P
Thanks for any more thoughts ....
|
|
|
|
|
Well, your desire for speed is certainly understandable. But it might be best to start out writing code that works, and then optimize it.
Anyway, as i said above: i doubt the CString buffer is being initialized. This means that in debug mode, it will contain 0xdbdbdbdb (or some such filler meant to identify uninialized memory) but in release, it might be anything.
Do the following:
get rid of this line
if ( pszBuffer )
in this line, get rid of the bold part
while (*pszBuffer != '\0' && *pszKeyWord != '\0' )
You'll then be rather unsafe, but the program should work if i'm right. A correct solution would be to pass in the length of the buffer.
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
You are a genius. That actually worked. I can't believe it.
That is pretty weird.
I'm stunned because I thought that and have always heard that
CStrings were initialized to empty in their constructor.
But I mean, if I do this
CString strLine;
or
CString strLine = "";
Shouldn't the string be initalized to an empty string???
Hmmm...
-Julie
|
|
|
|
|
I still don't understand why that works:
void MyFunct( LPCTSTR& pszBuffer )
{
if ( pszBuffer )
do_something();
}
...
CString strLine;
LPCTSTR szBuffer = strLine.GetBuffer( 100 );
MyFunct( szBuffer )
....
How could szBuffer be null in release mode? If its pointing to strLine's
buffer, its definitely pointing to something non-null.
why does this work?
I'm mystified..
Thanks,
-Julie
|
|
|
|
|
Life is Full of Suprises
VC++ in debug mode assignes non-NULL values to newly allocated memory as a debug helper. This explains why it works in debug.
pszBuffer should not be NULL. I'm not sure why i told you to get rid of the line that checked for that. (not sure why i'm still on CP at 12:30AM either... great, another addiction)
However, the data pointed to by pszBuffer might easily be NULL. Especially the first character, since this would be the NULL terminator on an emtpy string. Internally, CString s maintain a length counter, so the actual databuffer can be any size. The NULL terminator is strictly for the convenience of C-style string handling routines that need to access the CString . Keep in mind how the standard C library functions work: strcpy() does not require a length specifier, but is a danger spot for buffer overruns if you are not careful, since it does not (and cannot) check that the destination buffer is large enough to hold the source string. strncpy() does require a length specifier, and uses that to operate safely.
This is why using a string class instead of raw C-style strings is nice; constantly having to make your code aware of the total size of buffers gets old in a hurry.
Anyway, sorry you have to be working on the weekend; good luck on your project!
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
Thanks, you have totally saved my life. I was full-on panicking
earlier this evening. whew!
|
|
|
|
|
I think I get it.
The content of the pointer could be anything, as you said.
Even though I said I wanted to allocate a certain amount
for a buffer using GetBuffer, the contents of the buffer
could be anything - including '\0', but it wouldn't be a '\0'
that I had asked for or put in there. It would just be random
memory. Oh jeez. weird. ok.
Thanks again,
-Julie
|
|
|
|
|
Hello,
I have a subclass from CDialogBar. I try tu put a IP control in it, but i can´t get the bytes in that control.
I see that happens not only with this control, it happens with any control that don´t be a edit...
What happens?
Thanks Codeprojects...
UI
|
|
|
|