-1

I have a simple function that simply adds two numbers and returns the output like below

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;

double addNum(double num1=0, double num2=0) {
    return num1 + num2;
}

int main(int argc, char** argv) {
    printf("%.1f + %.1f = %.1f \n", 5.22, 4.66, addNum(5.22, 4.66));
}

This works just fine. Now say I change my addNum function return type to string and change the format identifier in printf to %s

string addNum(double num1=0, double num2=0) {
    return to_string(num1 + num2);
}

int main(int argc, char** argv) {
    printf("%.1f + %.1f = %s \n", 5.22, 4.66, addNum(5.22, 4.66));
}

But now I get the below error

test.cpp:266:47: error: cannot pass non-POD object of type 'std::__1::string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') to variadic function;
      expected type from format string was 'char *' [-Wnon-pod-varargs]
    printf("%.1f + %.1f = %s \n", 5.22, 4.66, addNum(5.22, 4.66));
                          ~~                  ^~~~~~~~~~~~~~~~~~
test.cpp:266:47: note: did you mean to call the c_str() method?
    printf("%.1f + %.1f = %s \n", 5.22, 4.66, addNum(5.22, 4.66));
                                              ^
                                                                .c_str()
1 error generated.

I do not understand what's going on here. I am returning a string and gave %s as an identifier as expected. Then why is it still complaining? How do I fix it?

Souvik Ray
  • 2,899
  • 5
  • 38
  • 70
  • 3
    `std::string` is a completely different type from (const) `char*`. The compiler's giving you all the information you need. – chris Sep 12 '21 at 05:47
  • 1
    Your code seems to be a strange mix of "C" and "C++". stdio.h AND iostream? Also try to avoid default arguments. Anyway you try to print something that is not a (const char*) but a std::string. You must use addNum(5.22,4.66).c_str() to be able to do that. Advise : change your code to use std::cout instead of printf – Pepijn Kramer Sep 12 '21 at 05:49

2 Answers2

1

Not a direct answer to your question, but I want to teach about not using printf. Since using printf is not secure/dangerous. Why not use printf() in C++

// #include <stdio.h> <== I would not use this in c++ 
#include <iostream>
#include <sstream>
#include <string>

// using namespace std; // I never use using namespace
double addNum(const double num1, const double num2) 
{
    return num1 + num2;
}

std::string addNumStr(const double num1, const double num2)
{
    std::stringstream os;
    os.setf(std::ios::fixed);
    os.setf(std::ios::showpoint);
    os.precision(1);

    os << (num1 + num2);
    return os.str();
}

int main(int /*argc*/, char** /*argv*/) 
{
    const double v1 = 5.22; // avoid mistakes when reusing same number in output
    const double v2 = 4.66;

    // some setup for formatting floating point numbers
    std::cout.setf(std::ios::fixed);
    std::cout.setf(std::ios::showpoint);
    std::cout.precision(1);

    // and output using std::cout
    std::cout << v1 << " + " << v2 << " = "<< addNum(v1, v2) << std::endl;

    // or like this, std::cout can handle std::string's directly
    // since there is an overload for operator<<(const std::string&), provided in <string> header
    std::cout << v1 << " + " << v2 << " = " << addNumStr(v1, v2) << std::endl;

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19
  • `printf()` is OK if you know what you are doing. – Michael Chourdakis Sep 12 '21 at 06:10
  • Yeah everything is ok if you know what you are doing. C++ is evolving, evolve with it. I like to teach new programmers the newer/safer/less buggy stuff directly. printf is a left-over from "C" and should imo no longer be used. – Pepijn Kramer Sep 12 '21 at 06:18
  • Not exactly. There are some things thar are *not* ok even if you know what you are doing, so they are deprecated/removed (like gets). The printf family is still usable and sometimes easier than cout. – Michael Chourdakis Sep 12 '21 at 08:30
  • @Kramer wow you taught me a lot of C++ here. Thanks! – Souvik Ray Sep 12 '21 at 11:42
  • I forgot to explain the "const"'s I added to the function, did you understand those too? In any casy happy to help – Pepijn Kramer Sep 12 '21 at 12:04
  • @MichaelChourdakis I think using printf/std::cout boils down to preference and what you're used to using. That said C++20 aknowledges formatting could still be improved and thus the format library will be added : https://en.cppreference.com/w/cpp/utility/format/format – Pepijn Kramer Sep 12 '21 at 12:08
1

printf was created a long time before C++ and does not have object support. %s expects a char* or char[] array and not a C++ string object, You can get the CString version by calling yourString.c_str(). It works for functions that return strings strFunction().c_str()

KleverFukk
  • 11
  • 1