Code, e.g.
printf(gettext("My name is %s.\n"), my_name); where gettext("My name is %s.\n") returns the translated string with default/reference (en) text My name is %s.\n here.

Comments for translators are prenended to gettext with ///

/// Keep %s intact. It will be replaced by the users name.
printf(gettext("My name is %s.\n"), my_name);

To generate a template translation file (with all translate-able strings), with the file extension .pot:
xgettext --add-comments=/

The .pot file looks like

#. TRANSLATORS: Please leave %s as it is, because it is needed by the program.
#. Thank you for contributing to this project.
#: src/name.c:36
msgid "My name is %s.\n"
msgstr ""

For a translation, a .po (PO = Portable Object) file is derived from the template file:
msginit --locale=fr --input=name.pot

The po syntax looks like:

#: src/name.c:36
msgid "My name is %s.\n"
msgstr "Je m'appelle %s.\n"

The po files are edited by the translators to translate the text.

Po files will be compiled to .mo files for distribution and usage with msgfmt

On Unix like systems the environment variable LC_MESSAGES defines the language that is to be loaded if available.