第2章,[標簽 Win32] :Windows 的字符串函數

專欄導航

上一篇:第2章 :兼容 ASCII 字符與寬字符的 Windows 函數調用

回到目錄

下一篇:無

本節前言

在下面的文章鏈接里面,我們談到過,使用兼容版的字符串處理函數的知識。

第2章 :編寫兼容多字節字符集和 Unicode 字符集的 Windows 程序

在上面的鏈接里面,我們談到了,如何使用一個統一的字符串函數,使得,當我們定義了 UNICODE 標識符的時候,我們所用的字符串函數就會指向 Unicode 版的字符串函數。而當我們沒有定義 UNICODE 標識符的時候,我們所用的字符串函數會指向 ASCII 版的字符串函數。

比如說,我們常用的求字符串長度的函數,它的 ASCII 版為 strlen,Unicode 版為 wcslen,而兼容版為 _tcslen 。使用 _tcslen 的時候,如果我們定義了 UNICODE 標識符,則 _tcslen 就是 wcslen 。如果沒有定義 UNICODE 標識符,則 _tcslen 就是 strlen 。

類似地,還有許多其它的一些個字符串處理函數,也都有它們的 ASCII 版,Unicode 版與兼容版。

ASCII 版,其前綴為 str 。Unicode 版,則是將 str 前綴替換為 wcs 。而兼容版,則是將 str 前綴替換為 _tcs 前綴。

我們來列出一個表格,來展示幾個常用的字符串處理函數。

ASCII 版Unicode 版兼容版
strlenwcslen_tcslen
strcpywcscpy_tcscpy
strcatwcscat_tcscat
strcmpwcscmp_tcscmp

我們只是舉出了四組字符串函數,它們分別有 ASCII 版,Unicode 版和兼容版。每一組函數里面,都是說,如果定義了 UNICODE 標識符,則兼容版函數就等同于 Unicode 版函數。如果沒有定義 UNICODE 標識符,則兼容版函數就等同于 ASCII 版函數。

在這里,UNICODE 標識符與 _UNICODE 標識符,可以看作是同義語。

設置 _UNICODE 標識符的方法,在下面的文章鏈接中的【四.(二)】分節中有講解。

第2章 :編寫兼容多字節字符集和 Unicode 字符集的 Windows 程序

在本節里面呢,我們來講解的是另一種兼容版的字符串函數。

本節開始。

一.? ? Windows 的字符串函數

本節所述的幾個 Windows 字符串函數,它們的數量是有限的。前言部分所述的那種,以 _tcs 作為前綴的兼容版字符串函數,它支持的字符串函數的數目是比較多的。

而本節所述的幾個 Windows 字符串函數,它只是針對常用的幾個字符串函數,設置了兼容函數。

我們一個一個地來看吧。

(一)strlen 的 WIndows 兼容版字符串函數

strlen 的 Windows 兼容版字符串函數為 lstrlen 。使用方法如下所示。

nLength = lstrlen(pString);

在上面的代碼行中,假定 nLength 是一個 int 型變量,而參數 pString 則是一個字符串。

lstrlen 的使用方法與 strlen 是一樣的。strlen 的具體使用方法,請參考下述文章鏈接。

編程技能:字符串函數05,strlen

本節,不具體講 strlen,也不具體講 lstrlen 。如果你還不會使用 strlen,那么,你可以先去學習上面的鏈接所示的文章的內容。

這個 lstrlen,它的功能與 _tcslen 是類似的。當定義了 UNICODE 標識符的時候,lstrlen 就是 Unicode 版的字符串函數, lstrlenW?。如果沒有定義 UNICODE 標識符,則 lstrlen 就是 ASCII 版的字符串函數, lstrlenA 。lstrlenW 約等于 wcslen,lstrlenA 約等于 strlen 。

(二)strcpy 的 WIndows 兼容版字符串函數

strcpy 的 WIndows 兼容版字符串函數為 lstrcpy 。使用方法如下所示。

pString = lstrcpy(pString1, pString2);

lstrcpy 的第一個參數及其返回值,都是【TCHAR *】類型的。而第二個參數是【const TCHAR *】類型的。換一個說法,lstrcpy 的第一個參數及其返回值的類型為 LPTSTR,lstrcpy 的第二個參數的類型為 LPCTSTR 。

TCHAR,LPTSTR,LPCTSTR 的含義,請參閱下述文章鏈接。

參考課節:第2章 :Windows 字符數據類型

在上面的示例代碼中,lstrcpy 的執行效果是,將 pString2 字符串復制到 pString1 所指向的字符指針位置。返回值為 pString1,這個返回值被賦值給了 pString 變量。

lstrcpy 的使用方法與 strcpy 是一樣的。strcpy 的使用方法,請參考下述文章鏈接。

編程技能:字符串函數02,strcpy

lstrcpy 雖說與 strcpy 的使用方法相同,但是呢,在 Visual Studio 的環境里,存在著一點小的區別。那就是,默認情況下,你直接使用 strcpy,則 Visual Studio 會報錯,它會建議你使用安全版本的 strcpy_s 函數。如果你還是想要使用 strcpy 函數,你需要去設置一下編譯參數。設置方法,請參考下面的文章鏈接。

編程技能:字符串函數04,直接使用 strcpy,解決報錯

而使用 lstrcpy 的話,你不需要考慮設置編譯參數的問題,直接使用,Visual Studio 也不會報錯的。

這個 lstrcpy,它的功能與 _tcscpy?是類似的。當定義了 UNICODE 標識符的時候,lstrcpy?就是 Unicode 版的字符串函數, lstrcpyW 。如果沒有定義 UNICODE 標識符,則 lstrcpy?就是 ASCII 版的字符串函數, lstrcpyA 。lstrcpyW 約等于 wcscpy,lstrcpyA 約等于 strcpy 。

(三)strncpy?的 WIndows 兼容版字符串函數

strncpy?的 WIndows 兼容版字符串函數為 lstrcpyn 。使用方法如下所示。

pString = lstrcpyn(pString1, pString2, iCount);

在上面的案例代碼里面,lstrcpyn 的第一個參數與返回值的類型均為【TCHAR *】,也就是 LPTSTR 。第二個參數的類型為【const TCHAR *】,也就是 LPCTSTR 。第三個參數的類型為 int 。

?TCHAR,LPTSTR,LPCTSTR 的含義,請參閱下述文章鏈接。

參考課節:第2章 :Windows 字符數據類型

lstrcpyn 的用法與 strncpy 是一樣的。strncpy 的用法,參考如下文章鏈接。

編程技能:字符串函數03,strncpy

?lstrcpyn 雖說與 strncpy 的使用方法相同,但是呢,在 Visual Studio 的環境里,存在著一點小的區別。那就是,默認情況下,你直接使用 strncpy,則 Visual Studio 會報錯,它會建議你使用安全版本的 strncpy_s 函數。如果你還是想要使用 strncpy 函數,你需要去設置一下編譯參數。設置方法,請參考下面的文章鏈接。

編程技能:字符串函數04,直接使用 strcpy,解決報錯

這個參考鏈接,你沒有看錯。我只給 strcpy 的報錯寫了糾錯方法。其余的,像是 strncpy,strcat,直接使用它們若是出現了安全版本警告,則解決思路都是設置編譯參數,設置方法與 strcpy 的糾錯方法是一樣的。

使用 strncpy,你需要考慮報錯的問題。而使用 lstrcpyn 的話,你不需要考慮設置編譯參數的問題,直接使用,Visual Studio 也不會報錯的。

這個 lstrcpyn,它的功能與 _tcsncpy?是類似的。當定義了 UNICODE 標識符的時候,lstrcpyn 就是 Unicode 版的字符串函數, lstrcpynW 。如果沒有定義 UNICODE 標識符,則 lstrcpy?就是 ASCII 版的字符串函數, lstrcpynA 。lstrcpynW 約等于 wcsncpy,lstrcpyA 約等于 strncpy 。

(四)strcat?的 WIndows 兼容版字符串函數

strcat?的 WIndows 兼容版字符串函數為 lstrcat 。使用方法如下。

pString = lstrcat(pString1, pString2);

lstrcat?的第一個參數及其返回值,都是【TCHAR *】類型的。而第二個參數是【const TCHAR *】類型的。換一個說法,lstrcat?的第一個參數及其返回值的類型為 LPTSTR,lstrcpy 的第二個參數的類型為 LPCTSTR 。

TCHAR,LPTSTR,LPCTSTR 的含義,請參閱下述文章鏈接。

參考課節:第2章 :Windows 字符數據類型

在上面的示例代碼中,lstrcat?的執行效果是,將 pString2 字符串拼接到 pString1 所指向的字符指傳的后面。返回值為 pString1,這個返回值被賦值給了 pString 變量。

lstrcat?的使用方法與 strcat?是一樣的。strcat?的使用方法,請參考下述文章鏈接。

參考課節:編程技能:字符串函數06,strcat

lstrcat?雖說與 strcat?的使用方法相同,但是呢,在 Visual Studio 的環境里,存在著一點小的區別。那就是,默認情況下,你直接使用 strcat,則 Visual Studio 會報錯,它會建議你使用安全版本的 strcat_s 函數。如果你還是想要使用 strcat?函數,你需要去設置一下編譯參數。設置方法,請參考下面的文章鏈接。

編程技能:字符串函數04,直接使用 strcpy,解決報錯

這個參考鏈接,你沒有看錯。我只給 strcpy 的報錯寫了糾錯方法。其余的,像是 strncpy,strcat,直接使用它們若是出現了安全版本警告,則解決思路都是設置編譯參數,設置方法與 strcpy 的糾錯方法是一樣的。

使用 strcat?函數,你需要考慮報錯的問題。而使用 lstrcat?的話,你不需要考慮設置編譯參數的問題,直接使用,Visual Studio 也不會報錯的。

這個 lstrcat,它的功能與 _tcscat?是類似的。當定義了 UNICODE 標識符的時候,lstrcat?就是 Unicode 版的字符串函數, lstrcatW 。如果沒有定義 UNICODE 標識符,則 lstrcat?就是 ASCII 版的字符串函數, lstrcatA 。lstrcatW 約等于 wcscat,lstrcatA 約等于 strcat?。

(五)strcmp?的?WIndows 兼容版字符串函數

strcmp?的?WIndows 兼容版字符串函數為 lstrcmp 。使用方法如下。

nComp = lstrcmp(pString1, pString2);

lstrcmp 的返回值為 int 類型,第一個參數和第二個參數均為【const TCHAR *】類型。【const TCHAR *】類型與 LPCTSTR 類型同義。

TCHAR,LPTSTR,LPCTSTR 的含義,請參閱下述文章鏈接。

參考課節:第2章 :Windows 字符數據類型

lstrcmp?的使用方法與 strcmp?是一樣的。strcmp?的使用方法,請參考下述文章鏈接。

參考課節:編程技能:字符串函數08,strcmp

這個 lstrcmp,它的功能與 _tcscmp?是類似的。當定義了 UNICODE 標識符的時候,lstrcmp?就是 Unicode 版的字符串函數, lstrcmpW 。如果沒有定義 UNICODE 標識符,則 lstrcmp?就是 ASCII 版的字符串函數, lstrcmpA 。lstrcmpW 約等于 wcscmp,lstrcmpA 約等于 strcmp?。

(六)strcmpi 及其 Windows 兼容版函數

strcmpi 函數,在預備章節里面,我并未講它。

strcmpi 函數,與 strcmp 函數相似,都是用于字符串比較。兩個函數的返回值,參數類型和參數個數都是相同的。不同的地方在于,strcmp 會區分大小寫,而 strcmpi 執行不區分大小寫的字符串比較。

strcmpi 的 Windows 兼容版函數為 lstrcmpi 。使用方法如下。

nComp = lstrcmpi(pString1, pString2);

本函數與上面的 (五)分節中的 lstrcmp 是非常相似的。只是本函數的比較不區分大小寫。請大家參考 lstrcmp 的講解,自行腦補 lstrcmpi 的用法與要領。

二.? ? 列表總結

上面的內容挺多的,也挺繁瑣的。

我們列一個表格,大家大致地梳理一下。

ASCII 版Unicode 版兼容版
lstrlenAlstrlenWlstrlen
lstrcpyAlstrcpyWlstrcpy
lstrcpynAlstrcpynWlstrcpyn
lstrcatAlstrcatWlstrcat
lstrcmpAlstrcmpWlstrcmp
lstrcmpiAlstrcmpiWlstrcmpi

帶有英文字母 L 的對應小寫字母,l 前綴的幾個字符串函數,它們與帶有 _tcs 前綴的對應的字符串函數的功能類似。lstrlen 與 _tcslen 類似,lstrcat 與 _tcscat 類似,等等。

到了這里,本節也就差不多了。

結束語

在寫作本節之前,我以為,本節應該不會耗時太多。

可是,真的去寫的時候,才發現,寫起來,還是比較耗費時間的。

有的函數,還需要我親自到 VS2019 里面去測試,需要去聯機查詢 MSDN 的內容。

Windows 程序設計,寫起來,也還是有挑戰性的。

希望我能夠寫好本專欄。寫好的一大標志是,各位讀者在看本專欄的內容時,能夠看得懂,學得會。

我們都加油吧。

專欄導航

上一篇:第2章 :兼容 ASCII 字符與寬字符的 Windows 函數調用

回到目錄

下一篇:無

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87122.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87122.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87122.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java的SpringAI+Deepseek大模型實戰-會話記憶【三】

文章目錄 背景項目環境實現步驟第一步、定義會話存儲方式方式一、定義記憶存儲ChatMemory方式二、注入記憶存儲ChatMemory 第二步、配置會話記憶方式一、老版本實現方式二、新版本實現 第三步、添加會話ID 異常處理1、InMemoryChatMemory 無法解析 背景 前兩期搭建起大模型對話…

Python3完全新手小白的學習手冊 10 文件和異常

文章目錄 讀取文件讀取文件的全部內容 相對路徑和絕對路徑訪問文件中的各行使用文件的內容包含100萬位的大型文件圓周率值中包含你的生日嗎? 寫入文件寫入一行寫入多行 異常處理ZeroDivisionError異常使用try-except代碼塊else代碼塊處理FileNotFoundError異常分析文…

VC Spyglass:工具簡介

相關閱讀 VC Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828932.html?spm1001.2014.3001.5482 傳統上,基于仿真的動態驗證技術一直是功能驗證的核心方式。隨著現代SoC設計日益復雜,靜態驗證技術的引入變得愈發重要。 Synopsys的 VC Sp…

AWS RDS Aurora全局數據庫轉區域數據庫實戰指南:無縫遷移零停機

Aurora全局數據庫是AWS提供的跨區域高可用解決方案,但在某些場景下,我們需要將其轉換為普通區域數據庫。本文將詳細介紹這一轉換過程,并分享關鍵技術要點和實戰經驗。 一、全局數據庫與區域數據庫概述 AWS RDS Aurora全局數據庫是一種跨區域部署的數據庫架構,主要用于災備…

C++之路:函數重載與運算符重載

目錄 函數重載運算符重載C運算符重載范圍對照表注意事項 運算符重載語法全局運算符重載類內運算符重載下面以一個一元運算符為例,介紹特性1:下面介紹特性3:(必須類內重載的運算符?) 函數重載 函數重載是指同一個作用域…

七、SpringCloud 項目遷移至 K8s

七、SpringCloud 項目遷移至 K8s 文章目錄 七、SpringCloud 項目遷移至 K8s1、環境準備1.1 集群規劃1.2 SpringCloud 項目架構及遷移需求分析 2、遷移 Eureka 集群2.1 構建及容器化2.2 部署至 K8s2.3 創建通信Service 3、遷移網關服務3.1 構建及容器化3.2 部署至 K8s3.3 創建Se…

通過具有一致性嵌入的大語言模型實現端到端乳腺癌放射治療計劃制定|文獻速遞-最新論文分享

Title 題目 End-to-end breast cancer radiotherapy planning via LMMs with consistency embedding 通過具有一致性嵌入的大語言模型實現端到端乳腺癌放射治療計劃制定 01 文獻速遞介紹 近年來,受大型語言模型(LLM)啟發的新一代人工智…

MCP Chart Server服務本地部署案例

一、MCP Chart Server介紹 MCP Chart Server是一個專業的圖表生成服務,支持多種圖表類型,適用于數據可視化和分析。 MCP Chart Server是一種用于生成和呈現圖表的服務器端軟件。它提供了一個簡單而強大的方式,讓開發人員和系統管理員可以輕…

復合型浪涌保護器五大核心技術重構電氣防護體系

開篇:從傳統防護到智能守護的技術跨越 在電氣設備面臨浪涌威脅的防護場景中,浪涌保護器(SPD)始終扮演著關鍵角色。面對傳統SPD在漏電流、續流等方面的技術局限,行業領先企業通過技術整合開發出復合型SPD,以…

c# 詳細分析Task.sleep和Thread.sleep 的區別、使用場景和應用示例

文章目錄 Task.Delay vs Thread.Sleep 詳細分析與使用場景核心區別詳細分析Thread.SleepTask.Delay 性能考量綜合示例高級用法組合延遲與超時實現指數退避重試 總結建議 Task.Delay vs Thread.Sleep 詳細分析與使用場景 核心區別 Task.Delay 和 Thread.Sleep 都用于在代碼中引…

Vue 3 中的 `h` 函數詳解

h 函數是 Vue 3 中用于創建**虛擬 DOM 節點(VNode)**的核心函數,它是 Vue 渲染系統的基石。下面我將全面解釋它的作用、用法和重要性。 1. h 函數的基本概念 h 是 createVNode 的簡稱,來源于"hyperscript"的縮寫傳統。它的主要作用是&#x…

SoapCore 全面介紹:在 .NET Core 中實現 SOAP 服務的現代解決方案

一、什么是 SoapCore? 在現代微服務和 REST API 成為主流的今天,SOAP(Simple Object Access Protocol)看似已經被邊緣化,但在許多企業和政務系統中,SOAP 仍然是 重要的通信協議。特別是在金融、保險、醫療…

JDBC工具類和SQL 注入問題

在軟件開發中,數據庫安全與高效訪問一直是關鍵課題。本文將圍繞 SQL 注入問題的原理、解決方案,以及 JDBC 開發中的工具類演進和連接池技術展開探討,結合實際代碼示例,為開發者提供清晰的技術實踐指南。 SQL 注入問題的核心原理與…

2022年SEVC SCI2區,分數階蟻群算法FACA:一種基于分數階長期記憶的合作學習方法,深度解析+性能實測

目錄 1.摘要2.分數階微積分基礎知識3.分數階蟻群算法FACA4.分數階蟻群算法FACA數學證明與分析5.結果展示6.參考文獻7.代碼獲取8.算法輔導應用定制讀者交流 1.摘要 本文提出了一種新穎分數階蟻群算法(Fractional-Order Ant Colony Algorithm, FACA&#…

java+vue+SpringBoo數字科技風險報告管理系統(程序+數據庫+報告+部署教程+答辯指導)

源代碼數據庫LW文檔(1萬字以上)開題報告答辯稿ppt部署教程代碼講解代碼時間修改工具 技術實現 開發語言:后端:Java 前端:vue框架:springboot數據庫:mysql 開發工具 JDK版本:JDK1.…

YOLOv12_ultralytics-8.3.145_2025_5_27部分代碼閱讀筆記-augment.py

augment.py ultralytics\data\augment.py 目錄 augment.py 1.所需的庫和模塊 2.class BaseTransform: 3.class Compose: 4.class BaseMixTransform: 5.class CutMix(BaseMixTransform): 6.class CopyPaste(BaseMixTransform): 7.def v8_transforms(dataset, img…

跨芯片 AI 算子庫 FlagGems 正式加入PyTorch 基金會生態項目體系

2025年北京智源大會 PyTorch Day China 論壇上,PyTorch 基金會執行董事 Matt White 宣布高性能通用 AI 算子庫 FlagGems 項目獲得批準,正式加入 PyTorch 生態項目體系。Pytorch基金會于6月26日在推特上進行了官方宣布。 作為唯一支持多種AI芯片架構的算…

vue + vue-router寫登陸驗證的同步方法和異步方法,及頁面組件的分離和后端代碼

先寫一個用vue cdn寫一個登陸驗證的小示例后端代碼 前端719.html <div id"app"><div id"loginForm">//路由層&#xff0c;登陸頁和后臺主頁<router-link to"/">Login</router-link><router-link to"/home&quo…

.netcore 一個mvc到靜態html實現

一、新建Mvc項目 Program.cs添加攔截 二、添加一個集成測試 將頁面轉為html到wwwroot下面 UnitGenHtml.cs using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.VisualStudio.TestPlatform.TestHost;namespace SaaS.OfficialWeb…

實現Taro小程序+nut-ui左滑刪除效果

Taro小程序開發中&#xff0c;使用nut-ui組件&#xff0c;實現左滑刪除卡片效果&#xff08;自定義刪除按鈕樣式&#xff09; html代碼部分 <nut-swipe class"carBox" v-for"(item, index) in carList" :key"item" :ref"(el) > se…