strlen for UTF-8


 
Thread Tools Search this Thread
Top Forums Programming strlen for UTF-8
# 1  
Old 04-18-2010
strlen for UTF-8

My OS (Debian) and gcc use the UTF-8 locale. This code says that the char size is 1 byte but the size of 'a' is really 4 bytes.
Code:
int main(void)
{
    setlocale(LC_ALL, "en_US.UTF-8");

    printf("Char size: %i\nSize of char 'a': %i\nSize of Euro sign '€': %i\nLength of Euro sign: %i\n", sizeof(char), sizeof('a'), sizeof('€'), strlen("€"));

    return 0;
}

Quote:
Char size: 1
Size of char 'a': 4
Size of Euro sign '€': 4
Length of Euro sign: 3
How can I make it output this which is more logical. I modified CHAR_BIT in limits.h to 32 but it still outputs 1 byte. Did I do something wrong ?
Quote:
Char size: 4
Size of char 'a': 4
Size of Euro sign '€': 4
Length of Euro sign: 1
# 2  
Old 04-18-2010
  1. don't modify any system headers unless you know what you're doing
  2. even if you do, the changes won't show until you recompile the C library (and maybe the kernel), where the sizes of the datatypes are used.
  3. if you want multibyte characters, use the wchar_t type and associated functions
# 3  
Old 04-18-2010
AAGH. Don't modify limits.h! You will break the compiler.

The size of a UTF-8 (8 bits) char is one byte.

You code has issues - sizeof(something) tells you how much space the compiler allocates for something, not the length of a character of a string. The answer is 1 for a single char.

mblen() gets the length of wide characters in bytes, use on wide characters.
# 4  
Old 04-18-2010
Quote:
Originally Posted by pludi
  1. even if you do, the changes won't show until you recompile the C library (and maybe the kernel), where the sizes of the datatypes are used.
Ah, that's why. I thought it would only apply to the program being compiled.
Quote:
Originally Posted by jim mcnamara
The size of a UTF-8 (8 bits) char is one byte.
By default, yes, because in ASCII, 1 char = 1 byte, but making it equal to 32 bits (4 bytes) would be better suited for UTF-8 where chars can equal 4 bytes.



One of the things I wanted to point out: if 'a' is 4 bytes, isn't it overflowing char which is 1 byte ?

Last edited by cyler; 04-18-2010 at 02:00 PM..
# 5  
Old 04-18-2010
Quote:
Originally Posted by cyler
One of the things I wanted to point out: if 'a' is 4 bytes, isn't it overflowing char which is 1 byte ?
No. Because the type char is defined as being 1 byte. However, if the compiler thinks a character might be a multi-byte symbol, it might silently convert it to an character array, or a matching multi-byte type. If it's converted to an character array, sizeof will probably return the size of the pointer to it (int == 4 bytes), or the size of the internal type (Unicode = 32bit == 4 bytes). Which case matches I cannot tell, as I'm only doing educated guesses here.
# 6  
Old 04-18-2010
The default value for a single char in C is usually promoted to an int. sizeof(int) = 4
but that does not mean that a single 'a' character actually is that large - 4 bytes.

A char in UTF-8 is 1 byte.

Your compiler stores a single char variable in the space it uses for an int. That is the bottom line for all the confusion.

BTW: CHAR_BIT by standard is currently defined to be fixed at 8, regardless of how the compiler decides to promote it. And regardless of what the locale may be. Which is why you should not change it to 32.

See C99 standards 5.2.4.2.1 Sizes of integer types <limits.h>
# 7  
Old 04-19-2010
UTF8 is encoded in 8-bit segments but occasionally it can take more than one byte to encode a full character. So the number of characters is wholly unrelated to the number of characters in the string; changing a #define won't make it any more right. None of the usual strlen/sizeof/etc things apply to a system where character encodings aren't always the same size!

If you want to count the number of UTF-8 encoded characters in the string, as opposed to the physical length of the string in bytes, I once wrote code for a UTF8 getc. Use strlen to get the length of the datablock to feed it, then process UTF8 chars one by one until the end of the string to get the UTF8 char count.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

PHP: declared variables, strlen vs isset

greetings, pretty new to php and i think i might be missing some fundamental limitation of isset. i have two php scripts below that are executed by crond, one using --host X and one that does not. and below that are three different attempts at generating a command line that will be executed. the... (8 Replies)
Discussion started by: crimso
8 Replies

2. Programming

Segment fault related to strlen.S

Hello, This function was copied into my code, which was compiled without error/warning, but when executed there is always Segmentation fault at the end after the output (which seems correct!): void get_hashes(unsigned int hash, unsigned char *in) { unsigned char *str = in; int pos =... (7 Replies)
Discussion started by: yifangt
7 Replies

3. Linux

Help to Convert file from UNIX UTF-8 to Windows UTF-16

Hi, I have tried to convert a UTF-8 file to windows UTF-16 format file as below from unix machine unix2dos < testing.txt | iconv -f UTF-8 -t UTF-16 > out.txt and i am getting some chinese characters as below which l opened the converted file on windows machine. LANG=en_US.UTF-8... (3 Replies)
Discussion started by: phanidhar6039
3 Replies

4. UNIX for Dummies Questions & Answers

UTF-8 in xterm

I need to use sort, uniq, grep, wc,... and the like to work with lists of words in UTF-8 (the "words" being phonetic transcriptions using the IPA). I have been using Google a lot and I even found at least one previous post on this topic, but it didn't help. I tried following the instructions... (2 Replies)
Discussion started by: mregine
2 Replies

5. UNIX for Advanced & Expert Users

vi and UTF-8 errors

We just installed icu for UTF-8 compliance on our AIX 5.3 system. While usuing vi on some files we get the following error: ex: 0602-169 Incomplete or invalid multibyte character encountere yte character encountered, conversion failed.ex: 0602-169 Incomplete or invalidb ractersultibyte... (0 Replies)
Discussion started by: jlacasci
0 Replies

6. Programming

pointer arithmetic vs. strlen() & strnlen()?

I have been getting some flack recently for my use of strlen() and strnlen(). Honestly I have always just taken their functionality for granted as being the easiest way of getting the length of a string. Is it really so much better to do pointer arithmetic? What am I gaining besides more... (3 Replies)
Discussion started by: jjinno
3 Replies

7. Programming

'strlen' of a constant string

In a declaration, I have: const char comment_begin = "<!--"; const char comment_end = "-->"; const int comment_begin_len = strlen(comment_begin); const int comment_end_len = strlen(comment_end); When I compile, I get the warnings: emhttpc.c:64: warning: initializer element is not... (10 Replies)
Discussion started by: cleopard
10 Replies

8. Shell Programming and Scripting

UTF 8 and SED

Collegues I tried to manipulate a UTF 8 data using the following script. cat $1 | sed 's/ലായി$/ലായി LAYI/g' | sed 's/ുടെ/ുടെ UTE/g' | sed 's/യില്*/യില്* YIL/g' But it says that cnot exicute binary file. Any solution. Jaganadh. Linguist (1 Reply)
Discussion started by: jaganadh
1 Replies

9. Shell Programming and Scripting

Problem with the strlen function in ksh

Hello, Just a little problem with the ksh function : strlen I want to use this function in this little ksh program : while read line ; do TOTO=$line TOTONB=strlen($TOTO) echo $TOTONB (3 Replies)
Discussion started by: steiner
3 Replies

10. Programming

Problems with Strlen

hello, i have a problem with strlen. I have written this: for(y=13,z=0; cInBuf!=' ';y++) { cBuf=cInBuf; z++; } len = strlen(cBuf); out=len/2; fprintf(outfile,"F%i",out); If strlen is e.g. 22, it write F22. I want to write F2F2. How can i do this?... (5 Replies)
Discussion started by: ACeD
5 Replies
Login or Register to Ask a Question