tags:

views:

79

answers:

3

I'm a beginner, I play with FindFirstFileW() of the winapi - C. The unicoded path is: " \\?\c:\Français\", and I would like to concat "*" to this path of type wchar_t (then I will use it as an arg for FindFirstFileW()).

I made two test cases of mine, the first is ansi_string() which seem to work fine, the second is unicode_string() - which I don't quite understand how should I concat the additional "*" char to the unicoded path. I write the strings to a file, because I'm not able to print Unicoded characters to stdout.

Note: my goal is to learn, which means I'll appreciate guidance and references to the appropriate resources regards my scenario, I'm very much a beginner and this is my first attempt with Unicode.

Thanks, Doori Bar

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <string.h>
#include <errno.h>

void *error_malloc(int size);

void ansi_string(char **str1, char **str2);

void unicode_string(wchar_t **wstr1, wchar_t **wstr2);

void unicode_string(wchar_t **wstr1, wchar_t **wstr2)
{
  /* assign wstr1 with the path: \\?\c:\Français\ */
  *wstr1 = error_malloc((wcslen(L"\\\\?\\c:\\Français\\")+1) *sizeof(**wstr1));
  wcscpy(*wstr1,L"\\\\?\\c:\\Français\\");

  /* concat wstr1+"*" , assign wstr2 with: \\?\c:\Français\* */
  *wstr2 = error_malloc((wcslen(*wstr1) + 1 + 1) * sizeof(**wstr1));
  /* swprintf(*wstr2,"%ls*",*wstr1); */
  /* how should I concat wstr1+"*"? */
   wcscpy(*wstr2,L"\\\\?\\c:\\Français\\");
}

void ansi_string(char **str1, char **str2)
{
  /* assign str1 with the path: c:\English\ */
  *str1 = error_malloc(strlen("c:\\English\\") + 1);
  strcpy(*str1,"c:\\English\\");

  /* concat str1+"*" , assign str2 with: c:\English\* */
  *str2 = error_malloc(strlen(*str1) + 1 + 1);
  sprintf(*str2,"%s*",*str1);
}

void *error_malloc(int size)
{
  void *ptr;
  int errornumber;
  if ((ptr = malloc(size)) == NULL) {
    errornumber = errno;
    fprintf(stderr,"Error: malloc(): %d; Error Message: %s;\n",
            errornumber,strerror(errornumber));
    exit(1);
  }
  return ptr;
}

int main(void)
{
  FILE *outfile;
  char *str1;
  char *str2;
  wchar_t *wstr1;
  wchar_t *wstr2;

  if ((outfile = fopen("out.bin","w")) == NULL) {
    printf("Error: fopen failed.");
    return 1;
  }

  ansi_string(&str1,&str2);
  fwrite(str2, sizeof(*str2), strlen(str2), outfile);
  printf("strlen: %d\n",strlen(str2));
  printf("sizeof: %d\n",sizeof(*str2));
  free(str1);
  free(str2);

  unicode_string(&wstr1,&wstr2);
  fwrite(wstr2, sizeof(*wstr2), wcslen(wstr2), outfile);
  printf("wcslen: %d\n",wcslen(wstr2));
  printf("sizeof: %d\n",sizeof(*wstr2));
  free(wstr1);
  free(wstr2);

  fclose(outfile);
  return 0;
}
+2  A: 

What's wrong with:

wchar_t *wcscat(wchar_t *dest, const wchar_t *src);

?

That should do the trick right?

xyld
Thanks for the fast response, this is how I applied it: wcscpy(*wstr2,*wstr1); wcscat(*wstr2,L"*");Doori Bar
Doori Bar
A: 

Based on your commented code you are trying to use swprintf so I will answer based on that.

In sprintf you can use %S for wide string parameters and %s for multi byte string parameters.

In swprintf you can use %s for wide string parameters and %S for multi byte character string parameters.

It's easy to remember if you just think that %s matches strings of the same type for the function you're using.

Example:

wchar_t wsz[1024];
char sz[1024];  
swprintf(wsz, L"%s %S", L"Hello", "world!");
sprintf(sz, "%S %s", L"Hello", "world!");
Brian R. Bondy
Isn't he looking to concatenate strings? not format them?
xyld
@xyld: If you look at his code he was trying to use swprintf, I am giving the answer that is what he is exactly looking for. Of course he can change the function he's using for string concat.
Brian R. Bondy
Thanks Brian, although the appropriate method would be to use wcscat(), I appreciate that you explained how I would've used swprintf() in this context:swprintf(*wstr2,L"%s%s",*wstr1,L"*");One more question, when I compiled your example: http://codepad.org/KXooLUCh under windows, using mingw: gcc -std=c99 , I got: "implicit declaration of function `swprintf'" , while doing the same under Linux, I got: "passing argument 2 of 'swprintf' makes integer from pointer without a cast" ... any idea?Doori Bar
Doori Bar
@Doori Bar: since you mentioned `FindFirstFile` I assumed you were using Windows. In Linux you'll hvae different format specifiers and functions.
Brian R. Bondy
+1  A: 

I would include "tchar.h" and use the unicode equivalents of the standard C library.

strcat("my\path\", "*");

becomes.

_tcscat(_T("my\path\"),_T("*"));

FYI: You can use the standard version of the function call without the 'W' on the end. The compiler will map the regular call to the correct version depending on the unicode settings of you app. Assuming it's either all Unicode or not.

Sophtware
What is tchar.h?
xyld
Thanks for the suggestion, as far as I managed to google your suggestion is windows-only. Even so my current need is based on a winapi function - I suppose using a more portable approach would be preferred, so I'll keep using the wcs* family.Regards your second comment - Thanks, I'll modify it accordingly.Doori Bar
Doori Bar