攔截 std::cout 的輸出結果

一般在寫 C++ 的程式的時候,大多會用標準輸出(standard output)來輸出文字、或是偵錯用的資訊。在標準函式庫裡面,針對輸出的部分就有提供 std::coutstd::cerrstd::clog,以及各自對應的寬字元版本。

但是在開發圖形介面的時候,往往不會顯示 console 視窗,所以這些訊息也就都看不到了。

而如果想要去攔截這些輸出的資訊,並將它們顯示在圖形介面裡面,該怎麼做呢?實際上,C++ 是允許是透過 rdbuf() 這個函式(參考),來取得或設定一個 stream 內部要使用的 stream buffer(參考)的。

也因此,透過這樣的機制,實際上是可以讓 std::cout 把資料寫到另外準備好的 stream buffer 中,然後再讀出來的!

閱讀更多»

廣告

C++ const 大亂鬥:const、constexpr、consteval、constinit

C++20 裡,以 const 為字首的關鍵字總共有四個:constconstexprconstevalconstinit;其中,const 應該是大家都熟系的老標準就有的,constexpr 則是在 C++11 的時候加入的;constevalconstinit 則是 C++20 的新東西。

這四種 const 到底差別是什麼呢?這邊參考《const vs constexpr vs consteval vs constinit in C++20》這篇文章、稍微整理一下這四種 const 的差別。

閱讀更多»

C++ 字串轉 chrono 的 time_point

最近碰到一個需求,是要去將一個代表日期、時間的字串轉換成 std::chronotime_point

查了一下後,在 C++20 的時候,針對 chrono 其實又提供了包含時區在內很多追加功能;其中就有一個 parse() 的函式、是用來針對自定義的格式分析字串、轉換成 time_point 的(文件)。下面就是一個實際的例子:

std::string s = "2022-11-11T11:11:11.111Z";
std::istringstream iss(s);

std::chrono::system_clock::time_point tp;

iss >> std::chrono::parse("%Y-%m-%dT%H:%M:%S", tp);
if (iss.fail())
  std::cerr << "failed" << "\n";
else
  std::cout << tp << "\n";

閱讀更多»

Visual C++ OpenMP 更新:支援 3.1 的 atomic

自從在 2021 年、Visual Studio 2019 開始引入 OpenMP LLVM 後,微軟終於開始有慢慢地開始針對 OpenMP 的標準支援進行更新了。

這次官方的公告是《MSVC OpenMP Update》,就是在介紹 Visual Studio 2022 17.4 中針對 C++ OpenMP 的更新了!官方的說法,是他們正在讓 Visual C++ 更符合 OpenMP 3.1 的標準。

這次更新的內容主要是:

  • 支援 OpenMP 3.1 的 #pragma omp atomic
  • 支援 min / max reduction
  • 支援指標型變數的 #pragma omp for

閱讀更多»

C++20 chrono 的日曆功能

很久以前,Heresy 曾經寫過 C++11 加入的 std::chrono 這個時間函式庫的介紹。而後來在 C++20 的時候,則又有在裡面追加「日曆」(calendar)喊「時區」(time zone)的功能,因為最近剛好有碰到這部分的東西,所以這邊就來稍微寫一下吧。

而這篇呢,就先針對日曆的部分來寫吧。

Chrono 提供的日曆的功能,主要針對了年、月、日都另外定義出了型別,而同時也提供了星期幾這樣的內容;進一步的,還有某個月的最後一天是幾號這類的訊息,對於某些印用來說,應該也算是有幫助的?

閱讀更多»

C++ 安全地比較 signed 和 unsigned

在強型別的 C++ 裡面,針對整數型別大多都有提供「有號」(signed、允許負數)和「無號」(unsigned、只有 0 和正數)兩種;像是以一般的整數來說,就有 intunsigned int 兩種,可以根據自己的需求來選擇要用哪種。

但是有的時候,我們難免會有需要要把資料在這兩種不同的中做轉換、或是拿來比較;而這個時候,其實是有相當的風險的…

像是以比較來說,可以來看下面這段程式碼:

#include <iostream>
 
int main()
{
  long           a = -100;
  unsigned short b = 100;
  size_t         c = 100;
 
  std::cout << (a < b);   // 1
  std::cout << (a < c);   // 2
}

閱讀更多»

C++ 的靜態多型:CRTP

這篇來寫個 C++ 的老東西、curiously recurring template pattern(CRTP、中文被翻譯成「奇異遞迴模板模式」、維基百科);這東西其實很早就有了,在 1980 年就有了,當時似乎是被稱為「F-bounded quantification」?

CRTP 基本上是一種 template + 繼承的變形語法、形式很特別,基本上會長的像下面的樣子:

template <class T>
class Base
{
public:
  void interface()
  {
    static_cast<T*>(this)->implementation();
  }
};
 
class Derived : public Base<Derived>
{
public:
  void implementation() {}
};

閱讀更多»

使用 Crypto++ 進行資料的加解密

這篇算是簡單紀錄一下,前陣子透過 Crypto++ 這個 C++ 的函式庫(官網GitHub)來進行資料加密、解密的紀錄。不過由於 Heresy 和密碼學不熟,所以這邊不會去解釋原理或各種方法,單純是針對怎麼用來做紀錄。

Crypto++ 基本的 header 檔案是 cryptlib.h,主要的 namespace 是 CryptoPP,在使用的時候基本上一定會用到;但是之後根據要使用的演算法,則也還需要另要加上個別的 header 才行。

而在要使用 Crypto++ 加解密的時候,要先決定要用哪種運作模式(mode、官方文件)、以及哪種 block cipher,然後才產生用來加解密的處理器。

閱讀更多»