String Formatting in C++

#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <bitset>

struct Point {
    int x, y;
};

int main() {
    // C++ offers several ways to format output. We'll use iostream and iomanip for most formatting.

    // This prints an instance of our Point struct.
    Point p{1, 2};
    std::cout << "struct1: " << p.x << " " << p.y << std::endl;

    // C++ doesn't have a built-in way to print struct field names, but we can define our own.
    std::cout << "struct2: {x:" << p.x << " y:" << p.y << "}\n";

    // There's no direct equivalent to Go's %#v, but we can create a similar output.
    std::cout << "struct3: Point{x:" << p.x << ", y:" << p.y << "}\n";

    // To print the type of a value, we can use typeid.
    std::cout << "type: " << typeid(p).name() << std::endl;

    // Formatting booleans
    std::cout << "bool: " << std::boolalpha << true << std::endl;

    // Formatting integers
    std::cout << "int: " << 123 << std::endl;

    // Binary representation
    std::cout << "bin: " << std::bitset<8>(14) << std::endl;

    // Character corresponding to an integer
    std::cout << "char: " << static_cast<char>(33) << std::endl;

    // Hexadecimal encoding
    std::cout << "hex: " << std::hex << 456 << std::endl;

    // Floating point formatting
    std::cout << "float1: " << std::fixed << std::setprecision(6) << 78.9 << std::endl;

    // Scientific notation
    std::cout << "float2: " << std::scientific << 123400000.0 << std::endl;
    std::cout << "float3: " << std::uppercase << std::scientific << 123400000.0 << std::endl;

    // String formatting
    std::cout << "str1: " << "\"string\"" << std::endl;

    // C++ doesn't have a direct equivalent to Go's %q, but we can create a similar output
    std::cout << "str2: \"\\\"string\\\"\"" << std::endl;

    // Hexadecimal representation of a string
    std::string hex_str = "hex this";
    std::cout << "str3: ";
    for (char c : hex_str) {
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(c);
    }
    std::cout << std::endl;

    // Printing a pointer
    std::cout << "pointer: " << &p << std::endl;

    // Controlling width and precision
    std::cout << "width1: |" << std::setw(6) << 12 << "|" << std::setw(6) << 345 << "|\n";
    std::cout << "width2: |" << std::fixed << std::setw(6) << std::setprecision(2) << 1.2 
              << "|" << std::setw(6) << 3.45 << "|\n";

    // Left-justification
    std::cout << "width3: |" << std::left << std::setw(6) << 1.2 << "|" << std::setw(6) << 3.45 << "|\n";

    // String width formatting
    std::cout << "width4: |" << std::right << std::setw(6) << "foo" << "|" << std::setw(6) << "b" << "|\n";
    std::cout << "width5: |" << std::left << std::setw(6) << "foo" << "|" << std::setw(6) << "b" << "|\n";

    // String formatting without printing (similar to Sprintf)
    std::ostringstream oss;
    oss << "sprintf: a " << "string";
    std::cout << oss.str() << std::endl;

    // Printing to stderr (similar to Fprintf)
    std::cerr << "io: an error\n";

    return 0;
}

To compile and run this program:

$ g++ -std=c++11 string_formatting.cpp -o string_formatting
$ ./string_formatting
struct1: 1 2
struct2: {x:1 y:2}
struct3: Point{x:1, y:2}
type: 5Point
bool: true
int: 123
bin: 00001110
char: !
hex: 1c8
float1: 78.900000
float2: 1.234000e+08
float3: 1.234000E+08
str1: "string"
str2: "\"string\""
str3: 6865782074686973
pointer: 0x7ffd5fbff6d0
width1: |    12|   345|
width2: |  1.20|  3.45|
width3: |1.20  |3.45  |
width4: |   foo|     b|
width5: |foo   |b     |
sprintf: a string
io: an error

This C++ code demonstrates various string and number formatting techniques. While C++ doesn’t have a built-in printf-style formatting, we can achieve similar results using the iostream library and manipulators from iomanip.

Some key differences from Go:

  1. C++ uses << operator for output streaming instead of functions like Printf.
  2. Formatting is often done using manipulators (like std::setw, std::setprecision, etc.) that affect subsequent output.
  3. C++ doesn’t have built-in verbs for formatting (like %v, %+v, %#v in Go), so we have to construct these manually where needed.
  4. For more complex formatting, you might want to use a third-party library like fmt or boost::format which provide printf-like formatting in C++.

Remember to compile with C++11 or later to ensure all features are available.