My test program works fine now after following a selected amount of advice above… Made a few changes and everything works. After replacing %s with %ls and replacing ”*MyString” with ”Mystring”, the program started to output expected strings. I then skipped ”wprintf” altogether and also ”fwide”. Didn't seem to be necessary in my case, and portability is not necessary in my case.
My string conversion function is just about the same as before, I will change it later. So far I only dereferenced it one step and changed ”main” accordingly. Main also prints both arguments now, not only argv[1]. This is the code at the moment:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <wchar.h>
#define VER "0.2"
#define PROGNAME "CountCharacters"
void UserErrorExit(void) {
fputs("Felaktigt antal parametrar.\n", stderr);
fputs("Läs den jävla manualen!\n\n", stderr);
fprintf(stderr,"man %s\n", PROGNAME);
exit(EXIT_FAILURE);
}
void MemoryErrorExit(void) {
fprintf(stderr, "Hoppsan, nu tog visst minnet slut här…\n");
exit(EXIT_FAILURE);
}
wchar_t *ToWide(const char *const mbs) {
size_t Len=mbstowcs(NULL, mbs, 0)+1;
wchar_t *newArray=malloc((Len)*sizeof(wchar_t));
if (newArray==NULL)
MemoryErrorExit();
Len=mbstowcs(newArray, mbs, Len)+1;
return (newArray);
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL, ""); // Use system's locale.
// Check user input. ——————————————————————————————————————————————————————————
if(argc<2 || argc>3)
UserErrorExit();
if(argc==2) {
if(strcmp(argv[1],"--version")==0) {
printf("Version: %s\n", VER);
return EXIT_SUCCESS;
}
else
UserErrorExit();
}
// ————————————————————————————————————————————————————————————————————————————
for(int i=1; i<=2; i++)
printf("%ls\n", ToWide(argv[i]));
return EXIT_SUCCESS;
}
Anyway, after a very quick study of the better (I suppose) function given earlier in this thread, I have a few beginner's questions about it, maybe somewhat off topic, but still…
Here's the function that I have questions about:
Code:
wchar_t *wide_string(const char *const s){
wchar_t *w;
size_t n, c;
if (!s) {
/* s is NULL. Set errno? */
return NULL;
}
n=mbstowcs(NULL, s, 0);
if (n==(size_t)-1) {
/* Invalid character in s. Set errno? */
return NULL;
}
w=malloc((n+1)*sizeof w[0]);
if (w==NULL) {
/* Out of memory. Set errno? */
return NULL;
}
if (n>0) {
c=mbstowcs(w, s, n+1);
if (c!=s) {
free(w);
/* s or locale was modified unexpectedly. Set errno? */
return NULL;
}
} else
w[0]=L'\0';
return w;
}
The very first line:
Code:
wchar_t *wide_string(const char *const s)
What's the difference between the two ”const”? I guess that the first is to prevent that the variable (or pointer in this case) is changed, but what's the other one for?
And why ”*const s”, why not ”const *s”? I tried both and both worked, as it seemed…
Another line:
I've been thinking about this one a little. Seems like it's checking if n==-1 after converting -1 to the size_t type, is that right? And is it really necessary to do that conversion? Shouldn't the compiler do that automatically?
Well, that was just about it, I think…
Again, thank you all very much for all help.