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;
}

 

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