Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which string manipulation functions should I use?

Tags:

c

string

On my Windows/Visual C environment there's a wide number of alternatives for doing the same basic string manipulation tasks.

For example, for doing a string copy I could use:

  • strcpy, the ANSI C standard library function (CRT)
  • lstrcpy, the version included in kernel32.dll
  • StrCpy, from the Shell Lightweight Utility library
  • StringCchCopy/StringCbCopy, from a "safe string" library
  • strcpy_s, security enhanced version of CRT

While I understand that all these alternatives have an historical reason, can I just choose a consistent set of functions for new code? And which one? Or should I choose the most appropriate function case by case?

like image 588
lornova Avatar asked Nov 15 '10 15:11

lornova


People also ask

How many types of string manipulation are there?

There are two types of methods in String : shared methods and instance methods.

What are the most common C standard library functions to manipulate strings?

In this lesson, we studied different functions that can be used to manipulate strings in C programming languages. The most commonly used functions are strlen(), strcmp() and strcpy().


1 Answers

First of all, let's review pros and cons of each function set:

ANSI C standard library function (CRT)

Functions like strcpy are the one and only choice if you are developing portable C code. Even in a Windows-only project, may it be a wise thing to have a separation of portable vs. OS-dependent code.
These functions have often assembly level optimization and are therefore very fast.
There are some drawbacks:

  • they have many limitations and therefore often you still have to call functions from other libraries or provide your own versions
  • there are some archaisms like the infamous strncpy

Kernel32 string functions

Functions like lstrcpy are exported by kernel32 and should be used only when trying to avoid any dependency to the CRT. You might want to do that for two reasons:

  • avoiding the CRT payload for an ultra lightweight executable (unusual these days but not 10 years ago!)
  • avoiding initialization issues (if you launch a thread with CreateThread instead of _beginthread).

Moreover, the kernel32 function could be more optimized that the CRT version: when your executable will run on Windows 9 optimized for a Core i13, kernel32 could use an assembly-optimized version.

Shell Lightweight Utility Functions

Here are valid the same considerations made for the kernel32 functions, with the added value of some more complex functions. However I doubt that they are actively maintained and I would just skip them.

StrSafe Function

The StringCchCopy/StringCbCopy functions are usually my personal choice: they are very well designed, powerful, and surprisingly fast (I also remember a whitepaper that compared performance of these functions to the CRT equivalents).

Security-Enhanced CRT functions

These functions have the undoubted benefit of being very similar to ANSI C equivalents, so porting legacy code is a piece of cake. I especially like the template-based version (of course, available only when compiling as C++). I really hope that they will be eventually standardized. Unfortunately they have a number of drawbacks:

  • although a proposed standard, they have been basically rejected by the non-Windows community (probably just because they came from Microsoft)
  • when fail, they don't just return an error code but execute an invalid parameter handler

Conclusions

While my personal favorite for Windows development is the StrSafe library, my advice is to use the ANSI C functions whenever is possible, as portable-code is always a good thing.

In the real life, I developed a personalized portable library, with prototypes similar to the Security-Enhanced CRT functions (included the powerful template based technique), that relies on the StrSafe library on Windows and on the ANSI C functions on other platforms.

like image 103
Wizard Avatar answered Oct 11 '22 15:10

Wizard