#include <iostream>
#include <string>
#include <vector>
 
struct person
{
    std::string firstName;
    std::string middleName;
    std::string lastName;
    std::string streetAddress1;
    std::string streetAddress2;
    std::string city;
    std::string state;
    std::string zip;
    static std::string GetPrintfFormatString()
    {
        static const char FormatString[] = R"(
First Name: %s
Middle Name: %s
Last Name: %s
Street Address 1: %s
Street Address 2: %s
City: %s
State: %s
Zip: %s
)";
        return FormatString;
    }
};

void PrintPersonWithPrintf(const person& p)
{
    ::printf(
        p.GetPrintfFormatString().c_str(),
        p.firstName.c_str(), p.middleName.c_str(), p.lastName.c_str(),
        p.streetAddress1.c_str(), p.streetAddress2.c_str(),
        p.city.c_str(), p.state.c_str(), p.zip.c_str());
}

void PrintPersonWithSPrintf(const person& p)
{
    std::string formatString = p.GetPrintfFormatString();
    size_t outputLen = formatString.length() + p.firstName.length()
        + p.middleName.length() + p.lastName.length()
        + p.streetAddress1.length() + p.streetAddress2.length()
        + p.city.length() + p.state.length() + p.zip.length()
        + 20;
    std::vector<char> buffer(outputLen, 0);
    ::sprintf(
        buffer.data(), formatString.c_str(),
        p.firstName.c_str(), p.middleName.c_str(), p.lastName.c_str(),
        p.streetAddress1.c_str(), p.streetAddress2.c_str(),
        p.city.c_str(), p.state.c_str(), p.zip.c_str());
	std::string out = buffer.data();
    std::cout << out;
}

int main()
{
	person me{
		"Benjamin",
		"Eugene",
		"Key",
		"12343 Some Street",
		"Apt 826",
		"Austin",
		"Texas",
		"78729"
	};
	PrintPersonWithPrintf(me);
    PrintPersonWithSPrintf(me);
	return 0;
}
