研究了很久,这是不是一个无解的问题?关于字符编码+管道。

AxYug 2014-05-06 02:40:57
下面代码,是在中文环境的Windows7+VS下编译出一个A.exe。

然后把这个A.exe,拿到英文操作系统下,用B.exe,通过管道,来获取这个"我"字,保存到一个wstring字符串里。


研究了很久,始终是解决不了。(我写的B.exe的代码如下,下面绿色的注释文字位置,就是管道读取到内容的地方。)




========================================A.exe代码:


#include <Windows.h>
#include <iostream>
#include <stdio.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
setlocale(LC_ALL, "chs");
std::cout << "我" <<std::endl;
return 0;
}











=========================================B.exe代码:




#include <Windows.h>
#include <stdio.h>
#include <assert.h>
#include <stdint.h>


int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
SECURITY_ATTRIBUTES security_attributes = { 0 };
security_attributes.nLength = sizeof(security_attributes);
security_attributes.bInheritHandle = TRUE;
security_attributes.lpSecurityDescriptor = NULL;

HANDLE hReadPipe = NULL, hWritePipe = NULL;
if (::CreatePipe(&hReadPipe, &hWritePipe, &security_attributes, 0) != TRUE)
{
assert(false);
}

PROCESS_INFORMATION pipeProcessInfo = { 0 };
STARTUPINFOW startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
startupInfo.hStdError = hWritePipe;
startupInfo.hStdOutput = hWritePipe;
startupInfo.hStdInput = hReadPipe;
startupInfo.dwFlags = STARTF_USESTDHANDLES;

wchar_t commandLine[1024] = { L"A.exe" };
if (::CreateProcessW(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &pipeProcessInfo) != TRUE)
{
assert(false);
}
else
{
::CloseHandle(pipeProcessInfo.hProcess);
::CloseHandle(pipeProcessInfo.hThread);
}

while (true)
{
#define BUFFER_SIZE 4096
uint8_t readBuffer[BUFFER_SIZE] = { 0 };
DWORD dwRead = 0;
::PeekNamedPipe(hReadPipe, readBuffer, BUFFER_SIZE, &dwRead, 0, 0);
if (dwRead > 0)
{
if (::ReadFile(hReadPipe, readBuffer, dwRead, &dwRead, NULL) == TRUE)
{
//最终要在这里,把readBuffer的字节流内容,转换成wstring,内容是"我"
}
}
}

return 0;
}





...全文
148 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-05-06
  • 打赏
  • 举报
回复
Locale Use the setlocale function to change or query some or all of the current program locale information. “Locale” refers to the locality (the country and language) for which you can customize certain aspects of your program. Some locale-dependent categories include the formatting of dates and the display format for monetary values. For more information, see Locale Categories. Locale-Dependent Routines Routine Use setlocale Category Setting Dependence atof, atoi, atol Convert character to floating-point, integer, or long integer value, respectively LC_NUMERIC is Routines Test given integer for particular condition. LC_CTYPE isleadbyte Test for lead byte () LC_CTYPE localeconv Read appropriate values for formatting numeric quantities LC_MONETARY, LC_NUMERIC MB_CUR_MAX Maximum length in bytes of any multibyte character in current locale (macro defined in STDLIB.H) LC_CTYPE _mbccpy Copy one multibyte character LC_CTYPE _mbclen Return length, in bytes, of given multibyte character LC_CTYPE mblen Validate and return number of bytes in multibyte character LC_CTYPE _mbstrlen For multibyte-character strings: validate each character in string; return string length LC_CTYPE mbstowcs Convert sequence of multibyte characters to corresponding sequence of wide characters LC_CTYPE mbtowc Convert multibyte character to corresponding wide character LC_CTYPE printf functions Write formatted output LC_NUMERIC (determines radix character output) scanf functions Read formatted input LC_NUMERIC (determines radix character recognition) setlocale, _wsetlocale Select locale for program Not applicable strcoll, wcscoll Compare characters of two strings LC_COLLATE _stricoll, _wcsicoll Compare characters of two strings (case insensitive) LC_COLLATE _strncoll, _wcsncoll Compare first n characters of two strings LC_COLLATE _strnicoll, _wcsnicoll Compare first n characters of two strings (case insensitive) LC_COLLATE strftime, wcsftime Format date and time value according to supplied format argument LC_TIME _strlwr Convert, in place, each uppercase letter in given string to lowercase LC_CTYPE strtod, wcstod, strtol, wcstol, strtoul, wcstoul Convert character string to double, long, or unsigned long value LC_NUMERIC (determines radix character recognition) _strupr Convert, in place, each lowercase letter in string to uppercase LC_CTYPE strxfrm, wcsxfrm Transform string into collated form according to locale LC_COLLATE tolower, towlower Convert given character to corresponding lowercase character LC_CTYPE toupper, towupper Convert given character to corresponding uppercase letter LC_CTYPE wcstombs Convert sequence of wide characters to corresponding sequence of multibyte characters LC_CTYPE wctomb Convert wide character to corresponding multibyte character LC_CTYPE _wtoi, _wtol Convert wide-character string to int or long LC_NUMERIC
赵4老师 2014-05-06
  • 打赏
  • 举报
回复
setlocale #pragma setlocale( "locale-string" ) Defines the locale (country and language) to be used when translating wide-character constants and string literals. Since the algorithm for converting multibyte characters to wide characters may vary by locale or the compilation may take place in a different locale from where an executable file will be run, this pragma provides a way to specify the target locale at compile time. This guarantees that the wide-character strings will be stored in the correct format. The default locale-string is "C". The "C" locale maps each character in the string to its value as a wchar_t (unsigned short).
赵4老师 2014-05-06
  • 打赏
  • 举报
回复
String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character. String-Manipulation Routines Routine Use _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive) _mbsdec, _strdec, _wcsdec Move string pointer back one character _mbsinc, _strinc, _wcsinc Advance string pointer by one character _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another _mbsnbcmp Compare first n bytes of two multibyte-character strings _mbsnbcnt Return number of multibyte-character bytes within supplied character count _mbsnbcpy Copy n bytes of string _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case _mbsnbset Set first n bytes of multibyte-character string to specified character _mbsnccnt Return number of multibyte characters within supplied byte count _mbsnextc, _strnextc, _wcsnextc Find next character in string _mbsninc. _strninc, _wcsninc Advance string pointer by n characters _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent sprintf, _stprintf Write formatted data to a string strcat, wcscat, _mbscat Append one string to another strchr, wcschr, _mbschr Find first occurrence of specified character in string strcmp, wcscmp, _mbscmp Compare two strings strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive) strcpy, wcscpy, _mbscpy Copy one string to another strcspn, wcscspn, _mbscspn, Find first occurrence of character from specified character set in string _strdup, _wcsdup, _mbsdup Duplicate string strerror Map error number to message string _strerror Map user-defined error message to string strftime, wcsftime Format date-and-time string _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case strlen, wcslen, _mbslen, _mbstrlen Find length of string _strlwr, _wcslwr, _mbslwr Convert string to lowercase strncat, wcsncat, _mbsncat Append characters of string strncmp, wcsncmp, _mbsncmp Compare characters of two strings strncpy, wcsncpy, _mbsncpy Copy characters of one string to another _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string _strrev, _wcsrev,_mbsrev Reverse string _strset, _wcsset, _mbsset Set all characters of string to specified character strspn, wcsspn, _mbsspn Find first substring from one string in another string strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string strtok, wcstok, _mbstok Find next token in string _strupr, _wcsupr, _mbsupr Convert string to uppercase strxfrm, wcsxfrm Transform string into collated form based on locale-specific information vsprintf, _vstprint Write formatted output using a pointer to a list of arguments
AxYug 2014-05-06
  • 打赏
  • 举报
回复
locale是可以的,chs是gbk编码。我尝试过了。 你的程序是存在问题的,fgetws这个函数的使用,没有编码转换的功能,所以fgetws是不能解决我的问题的。
引用 6 楼 mujiok2003 的回复:
[quote=引用 3 楼 AxYug 的回复:] 好像不行呀。 你的环境是这样吗?: A.exe  在中文操作系统上编译 运行  则是在英文操作系统上 [quote=引用 1 楼 mujiok2003 的回复:]

//A.exe
#include <iostream>
#include <locale>
int main()
{
  std::locale chs("chs");
  std::wcout.imbue(chs);
  std::wcout << L"我";
  return 0;
}


//B.exe
// crt_popen.c
/* This program uses _popen and _pclose to receive a 
 * stream of text from a system process.
 */

#include <stdio.h>
#include <stdlib.h>

int main( void )
{

   wchar_t   psBuffer[128];
   FILE   *pPipe;

        /* Run DIR so that it writes its output to a pipe. Open this
         * pipe with read text attribute so that we can read it 
         * like a text file. 
         */

   if( (pPipe = _popen( ".\\A.exe", "rt" )) == NULL )
      exit( 1 );

   /* Read pipe until end of file, or an error occurs. */

   while(fgetws(psBuffer, 128, pPipe))
   {
      wprintf(psBuffer);
   }


   /* Close pipe and print return value of pPipe. */
   if (feof( pPipe))
   {
     printf( "\nProcess returned %d\n", _pclose( pPipe ) );
   }
   else
   {
     printf( "Error: Failed to read the pipe to the end.\n");
   }
}
[/quote] 英文系统上直接运行A.exe能出结果就行,如果不行,说明是locale的原因。找一个可以工作的locale就成。 [/quote]
AxYug 2014-05-06
  • 打赏
  • 举报
回复
locale是可以的,chs是gbk编码。我尝试过了。 你的程序是存在问题的,fgetws这个函数的使用,没有编码转换的功能,所以fgetws是不能解决我的问题的。
mujiok2003 2014-05-06
  • 打赏
  • 举报
回复
引用 3 楼 AxYug 的回复:
好像不行呀。 你的环境是这样吗?: A.exe  在中文操作系统上编译 运行  则是在英文操作系统上 [quote=引用 1 楼 mujiok2003 的回复:]

//A.exe
#include <iostream>
#include <locale>
int main()
{
  std::locale chs("chs");
  std::wcout.imbue(chs);
  std::wcout << L"我";
  return 0;
}


//B.exe
// crt_popen.c
/* This program uses _popen and _pclose to receive a 
 * stream of text from a system process.
 */

#include <stdio.h>
#include <stdlib.h>

int main( void )
{

   wchar_t   psBuffer[128];
   FILE   *pPipe;

        /* Run DIR so that it writes its output to a pipe. Open this
         * pipe with read text attribute so that we can read it 
         * like a text file. 
         */

   if( (pPipe = _popen( ".\\A.exe", "rt" )) == NULL )
      exit( 1 );

   /* Read pipe until end of file, or an error occurs. */

   while(fgetws(psBuffer, 128, pPipe))
   {
      wprintf(psBuffer);
   }


   /* Close pipe and print return value of pPipe. */
   if (feof( pPipe))
   {
     printf( "\nProcess returned %d\n", _pclose( pPipe ) );
   }
   else
   {
     printf( "Error: Failed to read the pipe to the end.\n");
   }
}
[/quote] 英文系统上直接运行A.exe能出结果就行,如果不行,说明是locale的原因。找一个可以工作的locale就成。
AxYug 2014-05-06
  • 打赏
  • 举报
回复
而且,更有一点是,我是在windows7的英文操作系统上,进行运行调试的。 windows7英文操作系统,是原生支持汉字库的。 (虽然我这个功能与是否支持汉字库无关,主要相关的,是字节流的编码转换)
引用 2 楼 xiaohuh421 的回复:
英语系统, 可能没有安装汉字库, 就算安装了汉字库也可能没有安装可用字体或者可用字库
AxYug 2014-05-06
  • 打赏
  • 举报
回复
跟汉字库是无关的,我是直接查看的二进制值的。 例如,"我"字的UNICODE编码内容是 0x11 0x62。 如果,最终在B.exe里,能够获取到 0x11和0x62,就表示功能实现了。
引用 2 楼 xiaohuh421 的回复:
英语系统, 可能没有安装汉字库, 就算安装了汉字库也可能没有安装可用字体或者可用字库
AxYug 2014-05-06
  • 打赏
  • 举报
回复
好像不行呀。 你的环境是这样吗?: A.exe  在中文操作系统上编译 运行  则是在英文操作系统上
引用 1 楼 mujiok2003 的回复:

//A.exe
#include <iostream>
#include <locale>
int main()
{
  std::locale chs("chs");
  std::wcout.imbue(chs);
  std::wcout << L"我";
  return 0;
}


//B.exe
// crt_popen.c
/* This program uses _popen and _pclose to receive a 
 * stream of text from a system process.
 */

#include <stdio.h>
#include <stdlib.h>

int main( void )
{

   wchar_t   psBuffer[128];
   FILE   *pPipe;

        /* Run DIR so that it writes its output to a pipe. Open this
         * pipe with read text attribute so that we can read it 
         * like a text file. 
         */

   if( (pPipe = _popen( ".\\A.exe", "rt" )) == NULL )
      exit( 1 );

   /* Read pipe until end of file, or an error occurs. */

   while(fgetws(psBuffer, 128, pPipe))
   {
      wprintf(psBuffer);
   }


   /* Close pipe and print return value of pPipe. */
   if (feof( pPipe))
   {
     printf( "\nProcess returned %d\n", _pclose( pPipe ) );
   }
   else
   {
     printf( "Error: Failed to read the pipe to the end.\n");
   }
}
xiaohuh421 2014-05-06
  • 打赏
  • 举报
回复
英语系统, 可能没有安装汉字库, 就算安装了汉字库也可能没有安装可用字体或者可用字库
mujiok2003 2014-05-06
  • 打赏
  • 举报
回复

//A.exe
#include <iostream>
#include <locale>
int main()
{
  std::locale chs("chs");
  std::wcout.imbue(chs);
  std::wcout << L"我";
  return 0;
}


//B.exe
// crt_popen.c
/* This program uses _popen and _pclose to receive a 
 * stream of text from a system process.
 */

#include <stdio.h>
#include <stdlib.h>

int main( void )
{

   wchar_t   psBuffer[128];
   FILE   *pPipe;

        /* Run DIR so that it writes its output to a pipe. Open this
         * pipe with read text attribute so that we can read it 
         * like a text file. 
         */

   if( (pPipe = _popen( ".\\A.exe", "rt" )) == NULL )
      exit( 1 );

   /* Read pipe until end of file, or an error occurs. */

   while(fgetws(psBuffer, 128, pPipe))
   {
      wprintf(psBuffer);
   }


   /* Close pipe and print return value of pPipe. */
   if (feof( pPipe))
   {
     printf( "\nProcess returned %d\n", _pclose( pPipe ) );
   }
   else
   {
     printf( "Error: Failed to read the pipe to the end.\n");
   }
}

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧