LinuxC下wprintf和printf混用

译文部分

Linux C下
printf 和wprintf混用,仅一个有效果,另一个写返回-1.无errno信息,但是写失败。
问题解答链接
https://stackoverflow.com/questions/26816547/whats-the-difference-between-printfs-printfls-wprintfs-and-wp
标准解析链接https://en.cppreference.com/w/cpp/io/c
c流格式化和非格式的输入输出。是locale敏感的,可以宽字符或多字节的转换输出。
和C++流不一样,C++每个流关联自己的locale,
所有的C流获得相同的locale object,通过调用selocale加载。
此外,系统信息需要通过设备获取(如,一个POSIX的文件描述符)。每个C流object遵循
1字符宽度:没有设置,窄或宽
2缓冲区状态:无缓冲区,行缓冲,完全缓冲
3缓冲区,用扩展或用户提供的缓冲区
4I/O模式,输入、输出或更新(输入和输出)
5二进制/文本模式 指示
6文件结尾状态  指示
7 错误状态指示
8文件位置指示(类型对象std::fpos_t),对于宽字符流还包括解析规定(类型对象std::mbstate_t)
9(C++17)使用 Reentrant lock 防止多线程竞争流数据的读、写、定位、查询位置
窄和宽取向
一个新打开的流没有取向。第一次调用std::fwide或者其他的I/O函数建立取向:宽I/O函数设置流定宽,窄I/O函数使流定窄。
一旦设置,取向只能通过std::freopen改变。
窄I/O函数不可以调用定宽流,宽I/O函数不可以调用定窄流。
宽I/O函数使用std::mbrtowc和std::wcrtomb完成宽字符和多字节字符的转换。
和程序中的有效的多字节字符串不同,文件中的多字节字符可能潜入nulls并且不必以初始移入状态开始或结束。
POSIX要求当前的加载的C语言环境的LC_CTYPE在此刻流object变为定宽,并会被后续的I/O流使用直到取向改变,
不理会后续调用的setlocale();

wprintf 和printf不能同时针对同一个文件。
wprintf是宽流,窄串在内部被转为宽字符打印。
printf是窄流,宽字符在内部被转为窄串打印。

 wprinitf 字符串格式包含非ascii宽字符,程序只有在运行时的本区LC_CTYPE类型 和编译时本区LC_CTYPE类型一致时才能正常工作
/*
compile:gcc -Wall c.c
run:./a.out
check:cat f.txt
fileencoding:utf-8
locale 
stream-object
*/
#include<errno.h>
#include<wchar.h>
#include<string.h>
#include<stdio.h>
#include<locale.h>

void setplocale(int category,const char*locale)
{
char* rep;

rep=setlocale(category,locale);//query  current global locale
if(NULL!=rep)
  wprintf(L"%s\n",rep);
}

int main(){
freopen("f.txt","w",stdout);

setplocale(LC_ALL, ""); 


  int eno=0;
  int ret=0;
  char buffer[80];
  mbstate_t mbst;
  const wchar_t wcs [] = L"测试样例";
  const wchar_t * p;

  p = wcs;
  ret=wprintf(L"wprintf wchar_t %S\n",wcs);
  eno=errno;
  	if(-1==ret){

        if(eno>0)
	printf("%d %d:[%s]\n",ret,eno,strerror(eno));
	else 
 	 printf("Error writing\n");	
  	}
	if ( !mbsinit(&mbst) )//获得初始状态--初始状态不可更改
	memset (&mbst,0,sizeof(mbst));  /* set to initial state */
	wcsrtombs ( buffer, &p, 80, &mbst);
	wprintf(L"wprintf char    %s\n",buffer);
	fflush(stdout);
	freopen("f.txt","a+",stdout);//改变流取向
  	ret=printf(" printf char    %s \n",buffer);
 	ret=printf(" printf wchar_t %ls",wcs);
 	eno=errno;
  if(-1==ret)
  {
     printf("printf %d %d %s\n",ret,eno,strerror(eno));
	
  }
  


return 0;}
/* wprintf example */
#include <wchar.h>
#include<stdio.h>
int main()
{
   freopen("m.txt","w",stdout);
   fwide(stdout, 1);//-1:打印空,失败  1:打印成功
   //If the orientation of the stream has already been determined, fwide() shall not change it

   wprintf (L"Characters: %lc %lc \n", L'a', 65);
   wprintf (L"Decimals: %d %ld\n", 1977, 650000L);
   wprintf (L"Preceding with blanks: %10d \n", 1977);
   wprintf (L"Preceding with zeros: %010d \n", 1977);
   wprintf (L"Some different radixes: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
   wprintf (L"floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
   wprintf (L"Width trick: %*d \n", 5, 10);
   wprintf (L"%ls \n", L"A wide string");
   return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章