Click here to Skip to main content
15,309,875 members
Articles / Programming Languages / C#
Posted 20 Jun 2007


61 bookmarked

A printf implementation in C#

Rate me:
Please Sign up or sign in to vote.
4.41/5 (49 votes)
10 Feb 2015MIT3 min read
This article describes an implementation of printf using C#.

Screenshot - printf.jpg


While working on a project porting a large C/C++ Unix application into the .NET world, the language requirements changed from mixed C#/VB.NET/Managed C++ to C# (and only C#). In the C/C++ sources of this project, there were many [sf]printf statements. Migrating these to the corresponding C# String.Format format is not only annoying, but also a little problematic. This is because String.Format does not support all the required possibilities, as printf does. So, what to do? The solution was to implement a printf equivalent in C#, and that's what I will present to you in this article.

Using the code

Place a reference to the Tools assembly of the demo project, or incorporate my code into your source. Call Tools.printf with the appropriate parameters, and you are done. printf features a lot of conversion and formatting options -- far more than String.Format does -- but this comes at the price that it's also more complex, in case you have never used printf. To find out more about printf and its possibilities, have a look at the printf man page or just Google for man printf.

It is important to note that not all possible printf options, conversions, and formats are supported at the moment. There is also more than one printf implementation available on the 'net! This implementation supports the most common options. It supports the l and h length modifiers, all flags such as #+- ', and the following formats: iudxXfFeEgGon. There is no difference between ASCII and Unicode strings and characters; they are always Unicode.

printf outputs to the console. It also has variations like sprinf, which returns a formatted string, and fprinf, which writes formatted output to a stream. It supports variable length parameters. If there are more format placeholders than actual value parameters, then placeholders without a value will be removed from the result.

// Ouput: Account balance:       +12.345.678,00 (great)

Tools.printf("Account balance: %'+20.2f (%s)\n", 12345678, "great");

Building and testing the demo project

The demo project uses NUnit with test cases to test some printf features, but not all combinations of these. So, you will need NUnit installed.

Points of interest

Converting C/C++ code with lots of [sf]printf statements into C# is now a little easier. This printf implementation uses Regex \%([\'\#\-\+ ]*)(\d*)(?:\.(\d+))?([hl])?([dioxXucsfeEgGpn%]) to parse the format string and uses String.Format internally wherever possible. Strings are processed by hand only if not otherwise possible, so the code is quite simple and small.

Some people have pointed out that it is possible to use either the underlying unmanaged Windows API functions like:

[DllImport("msvcrt.dll",  SetLastError = false, 
  CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int sprintf(StringBuilder buff, string format, __arglist);
StringBuilder sb = new StringBuilder(256);
DateTime dt = DateTime.Now;
int hr = dt.Hour;
int mn = dt.Minute;
int sc = dt.Second;
int ml = dt.Millisecond;
MSVCRT.sprintf(sb, "%02i:%02i:%02i.%03i", __arglist(hr, mn, sc, ml));
string s = sb.ToString();

or a managed C++ wrapper called from C#:

namespace FormatHelper
    void FormatHelper::FormatDouble(String ^%sResult, String ^sFormat, double fVal)
        CString sStr;
        sStr.Format (CString(sFormat), fVal);
        sResult = gcnew String(sStr);

Call it like this from C#:

using FormatHelper;

string s = string.Empty;
Class1.FormatDouble(ref s, "%f6.1",132.459);

Both solutions will work, but sometimes it's not possible to use unmanaged code and other languages because of various reasons (Management - you know? ;-). That's because this is a complete rewrite of printf in C# without any dependencies.


Thanks to Rainer Helbing, this printf implementation now also supports parameter indices in the form of "%[parameterIndex][flags][width][.precision][length]type". A detailed description can be found here.

The NUnit test routines are also modified to work as expected with all Country settings for decimal and group separators.

A bug when specifying a precision with hex format was solved.


  • 2007.06.14 -- First release.
  • 2009.01.26 -- Update.


This article, along with any associated source code and files, is licensed under The MIT License


About the Author

Richard Prinz
Austria Austria
No Biography provided

Comments and Discussions

Generalexcellent! Pin
Southmountain9-May-17 15:21
MemberSouthmountain9-May-17 15:21 
Generalcongrats Pin
AndrzejBluzka23-Nov-16 7:15
MemberAndrzejBluzka23-Nov-16 7:15 
GeneralMy vote of 5 Pin
Andy Roberts18-Oct-16 10:56
MemberAndy Roberts18-Oct-16 10:56 
QuestionI have a hosted JavaScript emulator in .Net...wanted to offer printf style formatting ala node js... Pin
Eric Swann18-Feb-15 9:48
MemberEric Swann18-Feb-15 9:48 
Questionscanf Pin
mail-2212-Apr-12 2:03
Membermail-2212-Apr-12 2:03 
how about scanf ?

with respect
GeneralMy vote of 5 Pin
winxpdll8-Sep-11 20:32
Memberwinxpdll8-Sep-11 20:32 
GeneralMy vote of 5 Pin
fn567-Feb-11 4:35
Memberfn567-Feb-11 4:35 
QuestionHow about performance? Pin
2LM8-Mar-10 21:55
Member2LM8-Mar-10 21:55 
GeneralA couple of bugs Pin
st144-Jun-09 16:57
Memberst144-Jun-09 16:57 
AnswerRe: A couple of bugs [modified] Pin
danie_lidstrom30-Sep-10 4:28
Memberdanie_lidstrom30-Sep-10 4:28 
GeneralThanks, Code I can rely on. Pin
st143-May-09 2:59
Memberst143-May-09 2:59 
GeneralAlthough... Pin
bobpombrio22-Apr-09 4:03
Memberbobpombrio22-Apr-09 4:03 
AnswerRe: Although... Pin
Richard Prinz22-Apr-09 22:11
MemberRichard Prinz22-Apr-09 22:11 
GeneralMy vote of 1 Pin
CPAV27-Jan-09 7:44
MemberCPAV27-Jan-09 7:44 
GeneralRe: My vote of 1 Pin
Philippe Mori10-Feb-15 6:28
MemberPhilippe Mori10-Feb-15 6:28 
GeneralAlternative using MSVCRT sprintf Pin
JePo11-Dec-08 2:53
MemberJePo11-Dec-08 2:53 
Questiona Bug? Pin
eminsenay5-Jun-08 1:36
Membereminsenay5-Jun-08 1:36 
AnswerRe: a Bug? Pin
Richard Prinz26-Jan-09 5:06
MemberRichard Prinz26-Jan-09 5:06 
GeneralHere is an alternate solution Pin
Arthg17-Apr-08 10:55
MemberArthg17-Apr-08 10:55 
GeneralDubious Pin
wkempf20-Jun-07 9:46
Memberwkempf20-Jun-07 9:46 
AnswerRe: Dubious Pin
Richard Prinz20-Jun-07 22:18
MemberRichard Prinz20-Jun-07 22:18 
GeneralRe: Dubious Pin
wkempf21-Jun-07 2:47
Memberwkempf21-Jun-07 2:47 
GeneralRe: Dubious Pin
Richard Prinz21-Jun-07 4:40
MemberRichard Prinz21-Jun-07 4:40 
GeneralRe: Dubious Pin
Michael Lee Yohe25-Sep-07 5:03
MemberMichael Lee Yohe25-Sep-07 5:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.