CString maximum length - mfc

What is the maximum length in characters a CString object can hold?

Up to your available memory or INT_MAX-1 (whichever is less).

INT_MAX - 1

2,147,483,647 characters

Related

Space needed to store an unsigned integer into a char array and wide character array

I want to know how many bytes needed to store an unsigned integer into a character array and wide-character array.
char ar[25];
wchar_t w_ar[25];
size_t size_int;
size_int = sprintf(ar, "%u", UINT_MAX);
printf("\n size_int: %ld", size_int);
size_int = swprintf(w_ar, 25, L"%u", UINT_MAX);
printf("\n size_int: %ld", size_int);
In both the case I am getting 10 as the output. So I am going with 10, But UINT_MAX takes 4 bytes. What is this difference?
The 4 bytes (32 bits, binary digits) are the space required for the binary representation of the integer value.
10 decimal digits are required for the decimal representation. These can be represented as 10 printable characters, either using ASCII or 2-byte characters, or other encodings. So you get either one or half a decimal digit per byte.
The decimal digits also could be represented as 5 bytes of binary coded decimal values in some systems, with two decimal digits per byte, but you don't see that much now-a-days.
UINT_MAX tells you the largest value that an unsigned int may hold on your platform.
When you print it in decimal, then count the digits, that's not the same as number of bytes required to encode that value in binary (which is what happens inside your computer).
However, you can perform some arithmetic to find out how many decimal digits at maximum you may need to represent a value of this type, or ask numeric_limits::digits10 to do it for you.
Note that the resulting value will be conservative, as it rounds down; use the equivalent maths directly and round up to get an upper limit. (Unfortunately, max_digits10 is defined to be 0 for the integer types. 😭)
Don't forget that this is the number of digits, not the number of bytes needed for your string; for example, a UTF-16 string will need two bytes per digit.
Or just do it the way you did it.
You have to understand how radix work in mathematics, when dealing with positional number representation.
When you're talking about the radix, what you are saying is by how much the number vary, when moving to the next digit. In radix 10, there are 10 possible values per digit, so the value of a given digit will be 10^(x - 1) * digit x being the position, and you sum all these values to have the total value of the represented number.
We usually use decimal representation, while computer use binary representation. This means that when we use 4 octets to represent a number, the maximum number is 2^32 for an unsigned value.
However, sprintf used with the %u flag will convert that 32bits binary representation into a decimal one using character. Each character is taking enough memory space to store any character that could be represented. Assuming ascii, that's 128 different values, which take 7bits, and is stored as a byte (I used octet earlier, as it's usually a byte of 8bits on modern non-specialized hardware).
To wrap thing up, UINT_MAX, assuming 32bits integer, is 4,294,967,295, which take exactly 10 digits using a decimal representation. Were you using signed integer, it would be half that value, plus an additional minus character when the number is negative, thus taking 11 bytes.
If you were using hexadecimal, you'd count 2digit per bytes, so only 8 bytes to represent UINT_MAX (0xFFFFFFFF, but the 0x is optional, and is only used to indicate that the number following is written using hexadecimal representation).

Why are chars only 8 bits in size?

In most standard systems, a char is 8 bits in size. Using Shannon's equation:
8 bits = log2N
N must equal 256.
However, on the Unicode table there are far more than 256 characters. And on my compiler, when I run the following lines of code:
char c = static_cast<char> (257);
cout << c;
I see an unknown character printed to the screen, but a character nonetheless.
However, I've run some tests where I put many chars in a file, and the file's size corresponds with the char = 8 bit ratio.
So, it seems like a char is 8 bits (at least on my system), but I'm still seeing something printed to the screen at 257 and above, as well as there being many more chars than 256 on the unicode table.
char is guaranteed to be 1 byte by C++ standard. Keep in mind that it does not indicate that the size will be 8 bits, since not on every system the statement byte = 8 bits is true. For the sake of explanation, assume that we're talking only about 8 bit bytes.
First of all, when you write:
8 bits = log2N and thus N must equal 256
You are right. 8 bits can represent up to 256 different values, and the fact that Unicode consists of more characters than that has nothing to do with the problem. char is not meant to represent every possible character out there. It is meant to represent one of 256 different values that can be interpreted to some range of printable or non printable characters.
However, on the Unicode table there are far more than 256 characters. And on my compiler, when I run the following lines of code:
char c = static_cast<char> (257);
cout << c;
I see an unknown character printed to the screen, but a character nonetheless.
But have you tried actually determinatig what does static_cast<char>(257) return?
char c = static_cast<char>(257);
std::cout << static_cast<int>(c);
Will print 1, and as we dive into Unicode (or ASCII) table, we can see that this value represents the Start of Heading character. It is a non printable character and printing it will result in an undefined character appearing on the console (need confirmation whether or not this is truly undefined).
For printing a wider range of characters, consider using wchar_t (which is most likely to be 16 bits, thus it can cover a range of 65536 values) and std::wstring to correspond to it.
It is not mandatory that a char would always be 8 bits in size. char is dependent on CHAR_BIT variable defined in limits.h. CHAR_BIT value is usually 8 on most systems, but the actual value depends on the particular system and library implementation. You can find more details on limit.h header file here.
Two things:
If you run:
char c = static_cast<char> (257);
cout << static_cast<int> (c);
In most probable case you will see 1. The reason is indeed, char is 8-bit long and 257 is out of the range. In fact char c doesn't store 257 but 1.
The way you store string doesn't have an affect on how you display it. It depends on your console character encoding.
Char is 8 bit for historical reasons. When C programming was developed most output was on dumb terminals. The dumb terminals displayed characters based on the ASCII character encoding. ASCII characters ranged between 0 - 255. This handled most printable characters for English.
Considering all languages, there are much more than 256 characters. Additional character encoding were developed. Unicode is one, UTF-8 is another.
It really depends on what kind of coding algorithm you are using. As for ascii, it is only from 0 to 255.

Store a digit larger than 9 in array

I am wondering if it is possible to store a digit larger than 9 in an array. For example is
Int myarray[0] = 1234567898
From what I know about arrays they can only be integers in which the highest number will be a 9 digit number.
Is it possible to change the data type or have a larger digit. If not what are other ways to do it
It is quite possible. C++11 adds support for long long which is typically 64bit (much larger) that can store up to 19 digits and many compilers supported it before this as an extension. You can store arbitrarily large numbers in an array provided the array is large enough and you have the requisite mathematics. However, it's not pleasant and an easier bet is to download a library to do it for you. These are known as bignum or arbitrary size integer libraries and they use arrays to store integers of any size your machine can handle.
It's still not possible to express a literal above long long though.
A 32bit int has a max value of 2147483647 - that is 10 digits. If you need values higher than that, you need to use a 64bit int (long long, __int64, int64_t, etc depending on your compiler).
I am afraid that your idea that ints can only represent a single decimal digit is incorrect. In addition your idea that arrays can only hold ints is incorrect. An int is usually the computer's most efficient integral type. This is on most machines 16, 32 or 64 bits of binary data, thus can go up to 2^16 (65k), 2^32 (4million), or 2^64(very big). It is most likely 32 bits on your machine, thus numbers up to just over 4million can be stored. If you need more than that types such as long and long long are available.
Finally, arrays can hold any type, you just declare them as:
type myarray[arraysize];

C++: I have a string representing 8 bits. How Do I convert it to a char?

ie. "11111111" should convert to 0b11111111 / 255 (in dec)
Try strtol with a base of 2.
Another possibility would be value = std::bitset<8>("11111111").to_ulong(). This is more specialized for binary than strtol, so it could provide advantages if you might want to manipulate some bits. E.g., if you wanted to read a number, flip bit 5, and then convert.
You say specifically 8 bits, so:
static_cast<char>(std::bitset<8>(str).to_ulong());

Base 256 GUID String Representation w/Character Offset 0x01F

I need to make a string representation of a 128bit GUID that represents 8bit chunks instead of 4bit; so like base 256 :/ Why? Because I need to shorten the length of the string hex representation of the GUID, it is too long. I have a max array size of 31 plus NULL terminator. Also the character value cannot be from 0x000 to 0x01F.... It's giving me a headache but I know it can be done. Any suggestions on the best and safest way how? Right now I'm just mucking around with memcpy and adding 0x01F but the numbers keep bouncing around in my head.... can't nail 'em down no! And I have to interconvert :\
Try base64 encoding : it packs 6-bits per character and is still portable. You will need 22 chars to store 128 bits GUID in a portable way.
Having that OLESTR first convert it into a GUID with IIDFromString(), then use base64 as user Peter Tillemans suggests.