LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   wcslen / _tcslen not returning correct value (http://www.linuxquestions.org/questions/programming-9/wcslen-_tcslen-not-returning-correct-value-788625/)

hs_linux 02-12-2010 02:37 AM

wcslen / _tcslen not returning correct value
 
I have having some trouble working with wide characters, which is,

Sample code:
TCHAR fname[512];
_tcslcpy(fname, L"/root/Desktop/all/TheGrandTunnels.fgc", 512);
printf("%d", _tcslen(fname));

The output that I expect is 37 but it gives 19 (ie just half of 37).

Has it something to do with the locale setting?

I looked at makefiles and found the following,
WLOCALE = -fexec-charset=8859_1 -finput-charset=8859_1
AM_CXXFLAGS = $(WLOCALE)

Then I printed the return value of setlocale(LC_ALL, "") to know the current locale and it showed LC_CTYPE=en_US.UTF-8 and other subcategories were mainly "C". I then tried to set the current locale to 8859_1 (hoping that this might solve the problem) by calling,
char* curlocale = setlocale(LC_ALL, "en_US.ISO-8859-1");

But even after this, the value of wcslen is 19.

Please suggest.

paulsm4 02-12-2010 03:21 AM

Hi -

I'm not sure exactly what you're trying to do, what your platform is, what compiler you're using, or how your runtime environment is configured...

... But it sure sounds like you want to dump the binary value of "fname" after your "_tcslcpy()".

I'd start there.

IMHO .. PSM

hs_linux 02-12-2010 04:15 AM

I am using CentOS 4.7 and gcc as compiler. My application is a Java app which calls native C++ code through JNI. The code that I have mentioned above is in the C++ shared library. I am not setting up any environment variables for runtime use.

The code above pertains to a filename which I have hardcoded for time being (to be sure about where problems are originating). When this filename is converted to ansi string, the latter contains only half the string and therefore the file can't be opened. So, I put a _tcslen at source to see if the things are arriving correctly from the source. But unfortunately not. _tcslen returns the same length as is that of ansi string which is half of actual.

thanks.

paulsm4 02-12-2010 09:57 AM

'Sounds like a nightmare. JNI can be a *very* wily beast to try taming.

ANYWAY - my original suggestion still stands:
Quote:

you want to dump the binary value of "fname" after your "_tcslcpy()"
You need to see if "fname" is exactly 39 characters immediately after your "_tcslcpy()" (I'm reasonably sure it probably is).

You need to determine if "fname" is contiguous 8-bit bytes, or 16-bit wide characters. I'm not sure why you're using Unicode "L" constants, and I hope you don't think that changing the runtime locale (e.g. "$LANG") will at all affect a compile time constant (your string).

And once you completely understand what's happening at "_tcslcpy()", then you need to methodically trace the string from that point forward.

Good luck .. PSM

PS:
If you're using JNI, I'd strongly encourage you to use straight C: *not* C++.

hs_linux 02-16-2010 07:57 AM

Hi paulsm4,
Sorry for getting back late.
The problem was coming b'cos on linux the wchar_t is of 4 bytes, but in the library a compiler switch made it of 2 bytes.
So the compile time constant was 2 bytes per character but the api _tcslen assumes 4 bytes which is why length returned was half of actual.
And yes, I did dump the binary value of fname when the problem started occurring and it was always coming out correct.

thanks for showing interest in my post. regards.


All times are GMT -5. The time now is 07:04 AM.