kuga
kuga

Reputation: 1755

Correct way to printf() a std::string_view?

I am new to C++17 and to std::string_view. I learned that they are not null terminated and must be handled with care.

Is this the right way to printf() one?

#include<string_view>
#include<cstdio>

int main()
{
    std::string_view sv{"Hallo!"};
    printf("=%*s=\n", static_cast<int>(sv.length()), sv.data());
    return 0;
}

(or use it with any other printf-style function?)

Upvotes: 17

Views: 10617

Answers (4)

Michael S
Michael S

Reputation: 196

If using google's Abseil library (https://abseil.io/) the absl::PrintF function can safely print a string view (either std::string_view or absl::string_view).

From the Abseil documentation of absl::PrintF at https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_format.h

std::string_view s = "Ulaanbaatar";
absl::PrintF("The capital of Mongolia is %s", s);

Upvotes: 0

Marek R
Marek R

Reputation: 37892

This is strange requirement, but it is possible:

std::string_view s{"Hallo this is longer then needed!"};
auto sub = s.substr(0, 5);
printf("=%.*s=\n", static_cast<int>(sub.length()), sub.data());

https://godbolt.org/z/nbeMWo1G1

As you can see you were close to solution.

Upvotes: 20

Bill Weinman
Bill Weinman

Reputation: 2059

The thing to remember about string_view is that it will never modify the underlying character array. So, if you pass a C-string to the string_view constructor, the sv.data() method will always return the same C-string.

So, this specific case will always work:

#include <string_view>
#include <cstdio>

int main() {
    std::string_view sv {"Hallo!"};
    printf("%s\n", sv.data());
}

Upvotes: -6

eerorika
eerorika

Reputation: 238361

You can use:

assert(sv.length() <= INT_MAX);
std::printf(
    "%.*s",
    static_cast<int>(sv.length()),
    sv.data());

Upvotes: 10

Related Questions