- GUI
- Windows API tutorial
- Introduction to Windows API
- Windows API main functions
- System functions in Windows API
- Strings in Windows API
- Date & time in Windows API
- A window in Windows API
- First steps in UI
- Windows API menus
- Windows API dialogs
- Windows API controls I
- Windows API controls II
- Windows API controls III
- Advanced controls in Windows API
- Custom controls in Windows API
- The GDI in Windows API
- PyQt4 tutorial
- PyQt5 tutorial
- Qt4 tutorial
- Introduction to Qt4 toolkit
- Qt4 utility classes
- Strings in Qt4
- Date and time in Qt4
- Working with files and directories in Qt4
- First programs in Qt4
- Menus and toolbars in Qt4
- Layout management in Qt4
- Events and signals in Qt4
- Qt4 Widgets
- Qt4 Widgets II
- Painting in Qt4
- Custom widget in Qt4
- The Breakout game in Qt4
- Qt5 tutorial
- Introduction to Qt5 toolkit
- Strings in Qt5
- Date and time in Qt5
- Containers in Qt5
- Working with files and directories in Qt5
- First programs in Qt5
- Menus and toolbars in Qt5
- Layout management in Qt5
- Events and signals in Qt5
- Qt5 Widgets
- Qt5 Widgets II
- Painting in Qt5
- Custom widget in Qt5
- Snake in Qt5
- The Breakout game in Qt5
- PySide tutorial
- Tkinter tutorial
- Tcl/Tk tutorial
- Qt Quick tutorial
- Java Swing tutorial
- JavaFX tutorial
- Java SWT tutorial
- wxWidgets tutorial
- Introduction to wxWidgets
- wxWidgets helper classes
- First programs in wxWidgets
- Menus and toolbars in wxWidgets
- Layout management in wxWidgets
- Events in wxWidgets
- Dialogs in wxWidgets
- wxWidgets widgets
- wxWidgets widgets II
- Drag and Drop in wxWidgets
- Device Contexts in wxWidgets
- Custom widgets in wxWidgets
- The Tetris game in wxWidgets
- wxPython tutorial
- Introduction to wxPython
- First Steps
- Menus and toolbars
- Layout management in wxPython
- Events in wxPython
- wxPython dialogs
- Widgets
- Advanced widgets in wxPython
- Drag and drop in wxPython
- Internationalisation
- Application skeletons in wxPython
- The GDI
- Mapping modes
- Creating custom widgets
- Tips and Tricks
- wxPython Gripts
- The Tetris game in wxPython
- C# Winforms Mono tutorial
- Java Gnome tutorial
- Introduction to Java Gnome
- First steps in Java Gnome
- Layout management in Java Gnome
- Layout management II in Java Gnome
- Menus in Java Gnome
- Toolbars in Java Gnome
- Events in Java Gnome
- Widgets in Java Gnome
- Widgets II in Java Gnome
- Advanced widgets in Java Gnome
- Dialogs in Java Gnome
- Pango in Java Gnome
- Drawing with Cairo in Java Gnome
- Drawing with Cairo II
- Nibbles in Java Gnome
- QtJambi tutorial
- GTK+ tutorial
- Ruby GTK tutorial
- GTK# tutorial
- Visual Basic GTK# tutorial
- PyGTK tutorial
- Introduction to PyGTK
- First steps in PyGTK
- Layout management in PyGTK
- Menus in PyGTK
- Toolbars in PyGTK
- Signals & events in PyGTK
- Widgets in PyGTK
- Widgets II in PyGTK
- Advanced widgets in PyGTK
- Dialogs in PyGTK
- Pango
- Pango II
- Drawing with Cairo in PyGTK
- Drawing with Cairo II
- Snake game in PyGTK
- Custom widget in PyGTK
- PHP GTK tutorial
- C# Qyoto tutorial
- Ruby Qt tutorial
- Visual Basic Qyoto tutorial
- Mono IronPython Winforms tutorial
- Introduction
- First steps in IronPython Mono Winforms
- Layout management
- Menus and toolbars
- Basic Controls in Mono Winforms
- Basic Controls II in Mono Winforms
- Advanced Controls in Mono Winforms
- Dialogs
- Drag & drop in Mono Winforms
- Painting
- Painting II in IronPython Mono Winforms
- Snake in IronPython Mono Winforms
- The Tetris game in IronPython Mono Winforms
- FreeBASIC GTK tutorial
- Jython Swing tutorial
- JRuby Swing tutorial
- Visual Basic Winforms tutorial
- JavaScript GTK tutorial
- Ruby HTTPClient tutorial
- Ruby Faraday tutorial
- Ruby Net::HTTP tutorial
- Java 2D games tutorial
- Java 2D tutorial
- Cairo graphics tutorial
- PyCairo tutorial
- HTML5 canvas tutorial
- Python tutorial
- Python language
- Interactive Python
- Python lexical structure
- Python data types
- Strings in Python
- Python lists
- Python dictionaries
- Python operators
- Keywords in Python
- Functions in Python
- Files in Python
- Object-oriented programming in Python
- Modules
- Packages in Python
- Exceptions in Python
- Iterators and Generators
- Introspection in Python
- Ruby tutorial
- PHP tutorial
- Visual Basic tutorial
- Visual Basic
- Visual Basic lexical structure
- Basics
- Visual Basic data types
- Strings in Visual Basic
- Operators
- Flow control
- Visual Basic arrays
- Procedures & functions in Visual Basic
- Organizing code in Visual Basic
- Object-oriented programming
- Object-oriented programming II in Visual Basic
- Collections in Visual Basic
- Input & output
- Tcl tutorial
- C# tutorial
- Java tutorial
- AWK tutorial
- Jetty tutorial
- Tomcat Derby tutorial
- Jtwig tutorial
- Android tutorial
- Introduction to Android development
- First Android application
- Android Button widgets
- Android Intents
- Layout management in Android
- Android Spinner widget
- SeekBar widget
- Android ProgressBar widget
- Android ListView widget
- Android Pickers
- Android menus
- Dialogs
- Drawing in Android
- Java EE 5 tutorials
- Introduction
- Installing Java
- Installing NetBeans 6
- Java Application Servers
- Resin CGIServlet
- JavaServer Pages, (JSPs)
- Implicit objects in JSPs
- Shopping cart
- JSP & MySQL Database
- Java Servlets
- Sending email in a Servlet
- Creating a captcha in a Servlet
- DataSource & DriverManager
- Java Beans
- Custom JSP tags
- Object relational mapping with iBATIS
- Jsoup tutorial
- MySQL tutorial
- MySQL quick tutorial
- MySQL storage engines
- MySQL data types
- Creating, altering and dropping tables in MySQL
- MySQL expressions
- Inserting, updating, and deleting data in MySQL
- The SELECT statement in MySQL
- MySQL subqueries
- MySQL constraints
- Exporting and importing data in MySQL
- Joining tables in MySQL
- MySQL functions
- Views in MySQL
- Transactions in MySQL
- MySQL stored routines
- MySQL Python tutorial
- MySQL Perl tutorial
- MySQL C API programming tutorial
- MySQL Visual Basic tutorial
- MySQL PHP tutorial
- MySQL Java tutorial
- MySQL Ruby tutorial
- MySQL C# tutorial
- SQLite tutorial
- SQLite C tutorial
- SQLite PHP tutorial
- SQLite Python tutorial
- SQLite Perl tutorial
- SQLite Ruby tutorial
- SQLite C# tutorial
- SQLite Visual Basic tutorial
- PostgreSQL C tutorial
- PostgreSQL Python tutorial
- PostgreSQL Ruby tutorial
- PostgreSQL PHP tutorial
- PostgreSQL Java tutorial
- Apache Derby tutorial
- SQLAlchemy tutorial
- MongoDB PHP tutorial
- MongoDB Java tutorial
- MongoDB JavaScript tutorial
- MongoDB Ruby tutorial
- Spring JdbcTemplate tutorial
- JDBI tutorial
Strings in Windows API
In C language there is no string data type. A string literal in a program is an array of characters. Whenever we say string we mean an array of characters.
We have five sets of functions for working with strings; both in C runtime library (CRT) and in Windows API:
- ANSI C standard functions
- Security enhanced CRT functions
- Windows API kernel and user functions
- Windows API Shell Lightweight Utility functions
- Windows API StrSafe functions
It is recommended to prefer either security enhanced standard functions or Windows API safe functions.
ANSI C string functions
The C Run-Time (CRT) library functions have some small overhead since they call Windows API functions underneath. These functions provide portability but have some limitations. When not used properly, they can cause security risks.
These functions do not return an error value when they fail.
ansic_functions.c
#include <windows.h> #include <wchar.h> #define STR_EQUAL 0 int wmain(void) { wchar_t str1[] = L"There are 15 pines"; wprintf(L"The length of the string is %lld characters\n", wcslen(str1)); wchar_t buf[20]; wcscpy(buf, L"Wuthering"); wcscat(buf, L" heights\n"); wprintf(buf); if (wcscmp(L"rain", L"rainy")== STR_EQUAL) { wprintf(L"rain and rainy are equal strings\n"); } else { wprintf(L"rain and rainy are not equal strings\n"); } return 0; }
In the example we present a few string functions from the CRT library.
wprintf(L"The length of the string is %lld characters\n", wcslen(str1));
The wcslen()
returns the number of wide-characters in the string.
wcscpy(buf, L"Wuthering");
The wcscpy()
copies a string to a string buffer.
wcscat(buf, L" heights\n");
The wcscat()
function appends a string to a string buffer.
if (wcscmp(L"rain", L"rainy")== STR_EQUAL) { wprintf(L"rain and rainy are equal strings\n"); } else { wprintf(L"rain and rainy are not equal strings\n"); }
The wcscmp()
compares two string.
C:\Users\Jano\Documents\Pelles C Projects\strings\ANSICFunctions>ANSICFunctions.exe The length of the string is 18 characters Wuthering heights rain and rainy are not equal strings
This is the output of the example.
Security enhanced CRT functions
Security CRT functions add additional security to the CRT functions. (They are not standard functions but an MS extension.) These functions validate parameters, take size buffers, check that strings are NULL terminated, and provide enhanced error reporting.
Security CRT functions have an _s
suffix.
security_enhanced.c
#include <windows.h> #include <wchar.h> #define BUF_LEN 25 int wmain(void) { wchar_t str1[] = L"There are 15 pines"; const int MAX_CHARS = 50; size_t count = wcsnlen_s(str1, MAX_CHARS); wprintf(L"The length of the string is %ld characters\n", count); wchar_t buf[BUF_LEN] = {0}; int r = wcscpy_s(buf, BUF_LEN, L"Wuthering"); if (r != 0) { wprintf(L"wcscpy_s() failed %ld", r); } r = wcscat_s(buf, BUF_LEN, L" heights\n"); if (r != 0) { wcscat_s(L"wcscat_s() failed %ld", r); } wprintf_s(buf); return 0; }
In the example, we present four functions: wcsnlen_s()
, wcscpy_s()
, wcscat_s()
, and wprintf_s()
.
const int MAX_CHARS = 50; size_t count = wcsnlen_s(str1, MAX_CHARS);
The wcsnlen_s()
computes the lenght of a wide string. The function only checks the first MAX_CHARS
characters.
int r = wcscpy_s(buf, BUF_LEN, L"Wuthering");
With the wcscpy_s()
function, we copy the L"Wuthering"
string into the buffer. The function takes the maximum number of characters in the buffer and it returns an error code if it fails. The function returns 0 on success.
r = wcscat_s(buf, BUF_LEN, L" heights\n");
The wcscat_s()
is a secure extension of the wcscat()
function.
wprintf_s(buf);
There is even a security enhanced wprintf()
function; it has some runtime constraints.
C:\Users\Jano\Documents\Pelles C Projects\strings\SecurityEnhanced>SecurityEnhanced.exe The length of the string is 18 characters Wuthering heights
This is the output of the SecurityEnhanced.exe
example.
Windows API kernel and user string functions
These functions are specific to Windows OS; they are available in User32.lib
and Kernel32.lib
. They are lighter than their CRT counterparts.
Kernel string functions have their roots in the development of the Windows kernel. They are prefixed with the l
letter.
The string length
One of the most common requirements is to figure out the length of the string. The lstrlen()
function returns the length of the specified string in characters. It does not count the terminating null character.
int WINAPI lstrlenA(LPCSTR lpString); int WINAPI lstrlenW(LPCWSTR lpString);
The ANSI and the UNICODE functions take the string as a parameter and return the number of characters in the string.
winapi_string_lenght.c
#include <windows.h> #include <wchar.h> int wmain(void) { char *name = "Jane"; wchar_t *town = L"Bratislava"; wprintf(L"The length of the name string is %d\n", lstrlenA(name)); wprintf(L"The town string length is %d\n", lstrlenW(town)); return 0; }
We compute the length of two strings. The lstrlen()
function is in fact a macro to either lstrlenA()
or lstrlenW()
. The first is used for ANSI strings, the second for wide strings.
wprintf(L"The town string length is %d\n", lstrlenW(town));
We print the length of the L"Bratislava"
string using the lstrlenW()
function.
C:\Users\Jano\Documents\Pelles C Projects\strings\WinapiStringLength>WinapiStringLength.exe The length of the name string is 4 The town string length is 10
This is the output of the WinapiStringLength.exe
program.
Concatenating strings
The lstrcatW()
function appends one string to another string.
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2);
The first parameter is the buffer which should contain both strings. It must be large enough to contain both of them, including the NULL
terminating character. The return value is a pointer to the buffer.
winapi_string_concat.c
#include <windows.h> #include <wchar.h> int main(void) { wchar_t *s1 = L"ZetCode, "; wchar_t *s2 = L"tutorials "; wchar_t *s3 = L"for "; wchar_t *s4 = L"programmers.\n"; int len = lstrlenW(s1) + lstrlenW(s2) + lstrlenW(s3) + lstrlenW(s4); wchar_t buf[len+1]; lstrcpyW(buf, s1); lstrcatW(buf, s2); lstrcatW(buf, s3); lstrcatW(buf, s4); wprintf(buf); return 0; }
In the example, we concatenate four strings.
wchar_t *s1 = L"ZetCode, "; wchar_t *s2 = L"tutorials "; wchar_t *s3 = L"for "; wchar_t *s4 = L"programmers.\n";
These are the strings that we are going to concatenate.
int len = lstrlenW(s1) + lstrlenW(s2) + lstrlenW(s3) + lstrlenW(s4);
We compute the length of the four strings using the lstrlenW()
function.
wchar_t buf[len+1];
We create a buffer to hold the final string. Note that we add 1 to include the NULL
character.
lstrcpyW(buf, s1);
We copy the first string to the buffer using the lstrcpyW()
function.
lstrcatW(buf, s2); lstrcatW(buf, s3); lstrcatW(buf, s4);
We append the remaining strings with the lstrcatW()
function.
C:\Users\Jano\Documents\Pelles C Projects\strings\WinapiStringConcat>WinapiStringConcat.exe ZetCode, tutorials for programmers.
This is the output of the WinapiStringConcat.exe
program.
Converting characters
We have two methods for converting characters to uppercase or to lowercase. The CharLowerW()
function converts a character string or a single character to lowercase. The CharUpperW()
function converts a character string or a single character to uppercase. If the operand is a character string, the function converts the characters in place. In other words, they are modified.
LPWSTR WINAPI CharLowerW(LPWSTR lpsz); LPWSTR WINAPI CharUpperW(LPWSTR lpsz);
The functions modify the strings in place and return a pointer to the modified string.
winapi_string_case.c
#include <windows.h> #include <wchar.h> #pragma comment(lib, "User32.lib") int wmain(void) { wchar_t str[] = L"Europa"; CharLowerW(str); wprintf(L"%ls\n", str); CharUpperW(str); wprintf(L"%ls\n", str); return 0; }
We have one string which we convert to lowercase and uppercase.
CharLowerW(str); wprintf(L"%ls\n", str);
We convert the str
string to lowercase with the CharLowerW()
method. The string is modified in place.
C:\winapi\examples2\strings\UpperLower>UpperLower.exe europa EUROPA
This is the output of the UpperLower.exe
program.
Comparing strings
The lstrcmpW()
function compares two strings. It returns 0 if the strings are equal. The comparison is case sensitive. This means that "Cup" and "cup" are two different strings. The lstrcmpiW()
yields case insensitive string comparison. For this function, "Cup" and "cup" are equal.
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2); int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2);
The functions take two strings as parameters. The return value indicates the equality of the strings. 0 value is returned for equal strings.
winapi_string_compare.c
#include <windows.h> #include <wchar.h> #define STR_EQUAL 0 int wmain(void) { wchar_t *s1 = L"Strong"; wchar_t *s2 = L"strong"; if (lstrcmpW(s1, s2) == STR_EQUAL) { wprintf(L"%ls and %ls are equal\n", s1, s2); } else { wprintf(L"%ls and %ls are not equal\n", s1, s2); } wprintf(L"When applying case insensitive comparison:\n"); if (lstrcmpiW(s1, s2) == STR_EQUAL) { wprintf(L"%ls and %ls are equal\n", s1, s2); } else { wprintf(L"%ls and %ls are not equal\n", s1, s2); } return 0; }
We have two strings. We compare them using both case sensitive and case insensitive string comparison.
if (lstrcmpW(s1, s2) == STR_EQUAL) { wprintf(L"%ls and %ls are equal\n", s1, s2); } else { wprintf(L"%ls and %ls are not equal\n", s1, s2); }
If the lstrcmpW()
function returns STR_EQUAL
, which is defined to 0, then we print to the console that the two strings are equal. Otherwise we print that they are not equal.
C:\Users\Jano\Documents\Pelles C Projects\strings\WinapiStringCompare>WinapiStringCompare.exe Strong and strong are not equal When applying case insensitive comparison: Strong and strong are equal
The WinapiStringCompare.exe
program gives the above output.
Filling a buffer
Filling a buffer with formatted data is essential in C programming. The wsprintfW()
function writes formatted data to the specified buffer.
int __cdecl wsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, ... );
The function's first parameter is the buffer that is to receive the formatted output. The second is a string containing format-control specifications. Then we have one or more optional arguments which correspond to format-control specifications.
winapi_string_fillbuffer.c
#include <windows.h> #include <wchar.h> #pragma comment(lib, "User32.lib") int wmain(void) { SYSTEMTIME st = {0}; wchar_t buf[128] = {0}; GetLocalTime(&st); wsprintfW(buf, L"Today is %lu.%lu.%lu\n", st.wDay, st.wMonth, st.wYear); wprintf(buf); return 0; }
We build a string which is filled with the current date.
wchar_t buf[128] = {0};
In this particular case we can safely assume that the string will not exceed 128 characters.
GetLocalTime(&st);
The GetLocalTime()
function retrieves the current local date and time.
wsprintfW(buf, L"Today is %lu.%lu.%lu\n", st.wDay, st.wMonth, st.wYear);
The wsprintfW()
fills the buffer with a wide string. Arguments are copied to the string according to the format specifier.
wprintf(buf);
The content of the buffer is printed to the console.
C:\Users\Jano\Documents\Pelles C Projects\strings\WinapiStringFillBuffer>WinapiStringFillBuffer.exe Today is 11.2.2016
This is the output of the WinapiStringFillBuffer.exe
example.
Character types
Characters have various types. They can be digits, spaces, letters, punctuation, or control characters.
BOOL WINAPI GetStringTypeW(DWORD dwInfoType, LPCWSTR lpSrcStr, int cchSrc, LPWORD lpCharType);
The GetStringTypeW()
function retrieves character type information for the characters in the specified Unicode string. The first parameter is a flag specifying the info types.
Flag | Meaning |
---|---|
CT_CTYPE1 | Retrieve character type information. |
CT_CTYPE2 | Retrieve bidirectional layout information. |
CT_CTYPE3 | Retrieve text processing information. |
Table: Character info types
The second parameter is the Unicode string for which to retrieve the character types.
The third parameter is the size of the string. The final parameter is a pointer to an array of 16-bit values. The length of this array must be large enough to receive one 16-bit value for each character in the source string. The array will contain one word corresponding to each character in the source string.
The GetStringTypeW()
function returns a value which is a combination of types. We can query a specific type with the & operator.
Value | Meaning |
---|---|
C1_DIGIT | Decimal digits |
C1_SPACE | Space characters |
C1_PUNCT | Punctuation |
C1_CNTRL | Control characters |
C1_ALPHA | Any linguistic character |
Table: Partial list of character types
The function returns 0 on failure.
winapi_string_types.c
#include <windows.h> #include <wchar.h> #include <stdbool.h> int wmain(void) { wchar_t str[] = L"7 white, 3 red roses.\n"; int alphas = 0; int digits = 0; int spaces = 0; int puncts = 0; int contrs = 0; int size = lstrlenW(str); WORD types[size]; ZeroMemory(types, size); bool rv = GetStringTypeW(CT_CTYPE1, str, size, types); if (!rv) { wprintf(L"Could not get character types (%ld)", GetLastError()); return EXIT_FAILURE; } for (int i=0; i<size; i++) { if (types[i] & C1_ALPHA) { alphas++; } if (types[i] & C1_DIGIT) { digits++; } if (types[i] & C1_SPACE) { spaces++; } if (types[i] & C1_PUNCT) { puncts++; } if (types[i] & C1_CNTRL) { contrs++; } } wprintf(L"There are %ld letter(s), %ld digit(s), " L"%ld space(s), %ld punctuation character(s), " L"and %ld control character(s)\n", alphas, digits, spaces, puncts, contrs); return 0; }
We have a short sentence. The GetStringTypeW()
function is used to determine the character types of the string.
wchar_t str[] = L"7 white, 3 red roses.\n";
This is a short sentence consisting of various wide characters.
int alphas = 0; int digits = 0; int spaces = 0; int puncts = 0; int contrs = 0;
These variables will be used to count letters, digits, spaces, punctuation, and control characters.
int size = lstrlenW(str); WORD types[size]; ZeroMemory(types, size);
We get the size of the string and create and array of values. The size does not include the NULL
terminating character. We can add 1 to include it. It will be counted as a control character.
bool rv = GetStringTypeW(CT_CTYPE1, str, size, types);
We get the character types of the sentence. The types array is filled with character type values.
if (types[i] & C1_DIGIT) { digits++; }
If the value contains the C1_DIGIT
flag, we increase the digits counter.
C:\Users\Jano\Documents\Pelles C Projects\strings\WinapiStringTypes>WinapiStringTypes.exe There are 13 letter(s), 2 digit(s), 5 space(s), 2 punctuation character(s), and 1 control character(s)
This is the output of the WinapiStringTypes.exe
example.
Windows API Shell Lightweight Utility functions
These functions are specific to Windows OS; they are available in the Shlwapi.lib
.
Trimming a string
The StrTrimW()
function removes specified leading and trailing characters from a string. It returns true if any characters were removed; otherwise, false.
BOOL WINAPI StrTrimW(LPWSTR psz, LPCWSTR pszTrimChars);
The first parameter is a pointer to the string to be trimmed. When this function returns successfully, psz
receives the trimmed string. The second parameter is a pointer to a string that contains the characters to trim from psz
.
winapi_shell_trim.c
#include <windows.h> #include <wchar.h> #include <stdbool.h> #include "Shlwapi.h" #pragma comment(lib, "Shlwapi.lib") int wmain(void) { wchar_t buf[] = L"23tennis74"; wchar_t trim[] = L"0123456789"; wprintf(L"Original string: %ls\n", buf); bool r = StrTrimW(buf, trim); if (r == true) { wprintf(L"The StrTrim() trimmed some characters\n", buf); } else { wprintf(L"No characters were trimmed\n", buf); } wprintf(L"Trimmed string: %ls\n", buf); return 0; }
In the example, we remove any digits from a string.
wchar_t buf[] = L"23tennis74";
We will remove all digits from this string.
wchar_t trim[] = L"0123456789";
This string contains all characters to be removed.
bool r = StrTrimW(buf, trim);
With the StrTrimW()
function, we trim digits from the buffer.
C:\Users\Jano\Documents\Pelles C Projects\strings\ShellTrimString>ShellTrimString.exe Original string: 23tennis74 The StrTrim() trimmed some characters Trimmed string: tennis
This is the output of the ShellTrimString.exe
example.
Converting strings to integers
The StrToIntExW()
converts a string representing a decimal or hexadecimal number to an integer. The function returns true on success.
BOOL WINAPI StrToIntExW(LPCWSTR pszString, DWORD dwFlags, int *piRet);
The first parameter is a pointer to the string to be converted. The second parameter is one of the flags that specify how pszString
should be parsed for its conversion to an integer. The third parameter is a pointer to an int that receives the converted string.
winapi_shell_convert.c
#include <windows.h> #include <wchar.h> #include <stdbool.h> #include "Shlwapi.h" #pragma comment(lib, "Shlwapi.lib") int wmain(void) { wchar_t str1[] = L"512"; wchar_t str2[] = L"0xAB12"; int n = 0; bool r = StrToIntExW(str1, STIF_DEFAULT, &n); if (r == true) { wprintf(L"The value is %d\n", n); } else { wprintf(L"The first conversion failed\n"); return 1; } r = StrToIntExW(str2, STIF_SUPPORT_HEX, &n); if (r == true) { wprintf(L"The value is %d\n", n); } else { wprintf(L"The second conversion failed\n"); return 1; } return 0; }
In the example, we convert two strings; one representing a decimal value and one a hexadecimal one.
wchar_t str1[] = L"512"; wchar_t str2[] = L"0xAB12";
The first string represents a decimal number; the second string represents a hexadecimal number.
bool r = StrToIntExW(str1, STIF_DEFAULT, &n);
With the StrToIntExW()
function, we convert the first string into an integer. The STIF_DEFAULT
flag tells the function to convert a decimal value.
r = StrToIntExW(str2, STIF_SUPPORT_HEX, &n);
With the STIF_SUPPORT_HEX
flag, we tell the function to convert a hexadecimal value.
C:\Users\Jano\Documents\Pelles C Projects\strings\ShellConvertString>ShellConvertString.exe The value is 512 The value is 43794
This is the output of the ShellConvertString.exe
program.
Searching strings
The StrStrW()
function finds the first occurrence of a substring within a string. The comparison is case-sensitive.
LPWSTR WINAPI StrStrW(LPCWSTR pszFirst, LPCWSTR pszSrch);
The first parameter is a pointer to the string to search. The second parameter is a pointer to the substring to search for. The function returns the address of the first occurrence of the matching substring if successful, or NULL
otherwise.
winapi_shell_search.c
#include <windows.h> #include <wchar.h> #include "Shlwapi.h" #pragma comment(lib, "Shlwapi.lib") int wmain(void) { wchar_t buf[] = L"Today is a rainy day."; wchar_t *search_word = L"rainy"; int len = wcslen(search_word); LPWSTR pr = StrStrW(buf, search_word); if (pr == NULL) { wprintf(L"No match\n", buf); } else { wprintf(L"%.*ls is found\n", len, pr); } return 0; }
In the code example, we search for a word within a sentence.
wchar_t buf[] = L"Today is a rainy day.";
We search for a word from this sentence.
wchar_t *search_word = L"rainy";
This is the word that we search for.
LPWSTR pr = StrStrW(buf, search_word);
The StrStrW()
function searches for a word within the sentence. If it succeeds, it returns a pointer to the matching substring.
C:\Users\Jano\Documents\Pelles C Projects\strings\ShellSearchString>ShellSearchString.exe rainy is found
This is the output of the ShellSearchString.exe
program.
Windows API StrSafe functions
To increase application security, StrSafe functions were released. These functions require the size of the destination buffer as an input. The buffers are guaranteed to be null-terminated. The functions return error codes; this enables proper error handling.
Each of the functions is available in a corresponding character count Cch
or byte count Cb
version.
The string length
The StringCchLengthW()
and StringCbLengthW()
functions enable to determine the lenght of the string in characters and bytes.
HRESULT StringCchLengthW(LPCWSTR psz, size_t cchMax, size_t *pcch); HRESULT StringCbLengthW(LPCWSTR psz, size_t cbMax, size_t *pcb);
The first parameter of the functions is a string whose length is to be checked. The second parameter is the maximum number of characters (bytes) allowed in the psz
parameter. This value cannot exceed STRSAFE_MAX_CCH
. The third parameter is the number of characters (bytes) in psz
, not including the terminating null character.
The functions return S_OK
on success and STRSAFE_E_INVALID_PARAMETER
on failure. The functions fail if the value in psz
is NULL
, cchMax
is larger than STRSAFE_MAX_CCH
, or psz
is longer than cchMax
. The SUCCEEDED
and FAILED
macros can be used to check the return values of the functions.
safe_length.c
#include <windows.h> #include <strsafe.h> #include <wchar.h> int wmain(void) { wchar_t str[] = L"ZetCode"; size_t target_size = 0; size_t size = sizeof(str); HRESULT r = StringCbLengthW(str, size, &target_size); if (SUCCEEDED(r)) { wprintf(L"The string has %lld bytes\n", target_size); } else { wprintf(L"StringCbLengthW() failed\n"); return 1; } size = sizeof(str)/sizeof(wchar_t); r = StringCchLengthW(str, size, &target_size); if (SUCCEEDED(r)) { wprintf(L"The string has %lld characters\n", target_size); } else { wprintf(L"StringCchLengthW() failed\n"); return 1; } return 0; }
The code example determines the lenght of a given string in characters and bytes.
wchar_t str[] = L"ZetCode";
We are going to determine the length of this string.
size_t target_size = 0;
The target_size
variable is filled with the counted values when the functions return.
size_t size = sizeof(str);
With the sizeof
operator, we get the size of the array of characters in bytes. The value serves as a maximum allowable number of characters in the string for the StringCbLengthW()
function.
HRESULT r = StringCbLengthW(str, size, &target_size);
With the StringCbLengthW()
function we determine the length of the string in bytes. The length is stored in the target_size
variable.
if (SUCCEEDED(r)) { wprintf(L"The string has %lld bytes\n", target_size); } else { wprintf(L"StringCbLengthW() failed\n"); return 1; }
We check the returned value with the SUCCEEDED
macro. On success, we print the number of bytes in the string; on error, we print an error message.
size = sizeof(str)/sizeof(wchar_t);
Here we determine the maximum allowable characters in the string. The wchar_t
is a type for wide characters; its size is compiler specific.
r = StringCchLengthW(str, size, &target_size);
With the StringCchLengthW()
function, we get the size of the string in characters.
if (SUCCEEDED(r)) { wprintf(L"The string has %lld characters\n", target_size); } else { wprintf(L"StringCchLengthW() failed\n"); return 1; }
On success, we print the number of characters in the string to the console. On error, we print an error message.
C:\Users\Jano\Documents\Pelles C Projects\strsafe\SafeLength>SafeLength.exe The string has 14 bytes The string has 7 characters
The string consists of 14 bytes or 7 characters.
Reading standard input
The StringCchGetsW()
reads a line from the standard input, including the newline character.
HRESULT StringCchGetsW(LPWSTR pszDest, size_t cchDest);
The first parameter is the destination buffer, which receives the copied characters. The second parameter is the size of the destination buffer, in characters.
safe_gets.c
#include <windows.h> #include <strsafe.h> #include <wchar.h> #define BUF_LEN 8191 int wmain(void) { wchar_t buf[BUF_LEN] = {0}; HRESULT r = StringCchGetsW(buf, ARRAYSIZE(buf)); if (SUCCEEDED(r)) { wprintf(L"You have entered: %ls\n", buf); } else { wprintf(L"StringCchGets() failed\n"); return 1; } return 0; }
In the example we read a line from the standard input. The line is printed back to the console.
#define BUF_LEN 8191
According to the MSDN documentation, the maximum input on command prompt cannot exceed 8191 characters.
wchar_t buf[BUF_LEN] = {0};
We create a buffer for the input string.
HRESULT r = StringCchGetsW(buf, ARRAYSIZE(buf));
The StringCchGetsW()
reads a line from the stdin
.
C:\Users\Jano\Documents\Pelles C Projects\strsafe\SafeGets>SafeGets.exe Today is a rainy day. You have entered: Today is a rainy day.
This is a sample run of the SafeGets.exe
program.
Copying strings
The StringCchCopyW()
copies one string to another.
HRESULT StringCchCopyW(LPTSTR pszDest, size_t cchDest, LPCWSTR pszSrc);
The first parameter is the destination buffer, which receives the copied string. The second parameter is the size of the destination buffer, in characters. The third parameter is the source string.
safe_copy.c
#include <windows.h> #include <strsafe.h> #include <wchar.h> int wmain(void) { wchar_t *sentence = L"Today is a rainy day."; size_t size = wcslen(sentence) + 1; wchar_t buf[size]; ZeroMemory(buf, size); HRESULT r = StringCchCopyW(buf, size, sentence); if (SUCCEEDED(r)) { wprintf(L"%ls\n", buf); } else { wprintf(L"StringCchCopyW() failed\n"); return 1; } return 0; }
In the code example, we copy one string with the StringCchCopyW()
function.
wchar_t *sentence = L"Today is a rainy day.";
This is the string to be copied.
size_t size = wcslen(sentence) + 1;
We determine its length with the wcslen()
function; one character is reserved for the newline.
wchar_t buf[size]; ZeroMemory(buf, size);
We create a buffer and with it with zeros with the ZeroMemory()
function.
HRESULT r = StringCchCopyW(buf, size, sentence);
With the StringCchCopyW()
, we copy the string into the buffer. The size of the destination buffer is provided to ensure that it does not write past the end of this buffer.
C:\Users\Jano\Documents\Pelles C Projects\strsafe\SafeCopy>SafeCopy.exe Today is a rainy day.
This is the output of the SafeCopy.exe
program.
Concatenating strings
The StringCchCatW()
concatenates one string to another string.
HRESULT StringCchCatW(LPWSTR pszDest, size_t cchDest, LPCWSTR pszSrc);
The first parameter is the destination buffer. The second parameter is the size of the destination buffer, in characters. The third paramater is the source string that is to be concatenated to the end of the destination buffer.
safe_concat.c
#include <windows.h> #include <strsafe.h> #include <wchar.h> #define BUF_LEN 256 int wmain(void) { wchar_t buf[BUF_LEN] = {0}; HRESULT r = StringCchCatW(buf, BUF_LEN, L"Hello "); if (FAILED(r)) { wprintf(L"StringCchCatW() failed\n"); return 1; } r = StringCchCatW(buf, BUF_LEN, L"there"); if (FAILED(r)) { wprintf(L"StringCchCatW() failed\n"); return 1; } wprintf(L"%ls\n", buf); return 0; }
In the code example, we concatenate two strings with the StringCchCatW()
function.
HRESULT r = StringCchCatW(buf, BUF_LEN, L"Hello ");
The StringCchCatW()
function adds the L"Hello "
string to the buf array.
r = StringCchCatW(buf, BUF_LEN, L"there");
Later, the second string is added to the buffer.
C:\Users\Jano\Documents\Pelles C Projects\strsafe\SafeConcat>SafeConcat.exe Hello there
This is the output of the SafeConcat.exe
program.
Formatting strings
The StringCchPrintfW()
function writes formatted data to the destination buffer.
HRESULT StringCchPrintfW(LPWSTR pszDest, size_t cchDest, LPCWSTR pszFormat, ...);
The first parameter is the destination buffer, which receives the formatted string created from pszFormat
and its arguments. The second parameter is the destination buffer, in characters. The third parameter is the format string. The following arguments are inserted into the pszFormat
string.
safe_format.c
#include <windows.h> #include <strsafe.h> #include <wchar.h> #define BUF_LEN 256 int wmain(void) { wchar_t *word = L"table"; int count = 6; wchar_t buf[BUF_LEN] = {0}; wchar_t *line = L"There are %d %lss"; HRESULT r = StringCchPrintfW(buf, ARRAYSIZE(buf), line, count, word); if (SUCCEEDED(r)) { wprintf(L"%ls\n", buf); } else { wprintf(L"StringCchPrintfW() failed\n"); return 1; } return 0; }
In the code example, we create a formatted string with the StringCchPrintfW()
function.
wchar_t *line = L"There are %d %lss";
This is the format string; it has two format specifiers: %d
and %ls
.
HRESULT r = StringCchPrintfW(buf, ARRAYSIZE(buf), line, count, word);
With the StringCchPrintfW()
function, we insert two values into the destination buffer.
C:\Users\Jano\Documents\Pelles C Projects\strsafe\SafeFormat>SafeFormat.exe There are 6 tables
This is the output of the SafeFormat.exe
program.
In this part of the Windows API tutorial, we have worked with strings.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论