0

This is a follow up to my question yesterday.

I'm using a function to download a file:

void downloadFile(const char* url, const char* fname, const char* id ) {
  //..
}

This is called like :

downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt", "/home/user/Download/xxxx");

This works fine with a fixed id as shown, but I need xxxx to replaced with a random number:

srand(time(NULL));
int rdn = rand();

If I try:

downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt", "/home/user/Download/" + rdn);

I get

error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]

So how do I append rdn to the string "/home/user/Download/"? For example, if rdm == 123456789, I would like to pass "/home/user/Download/123456789" to the function.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Rocket
  • 1,065
  • 2
  • 21
  • 44
  • 4
    There is `sprintf` but **please** use `std::string` / `std::to_string`. – leemes Feb 11 '16 at 16:25
  • What exactly are you hoping to achieve with `"/home/user/Download/" + rdn`??? – barak manos Feb 11 '16 at 16:28
  • 3
    I'm very puzzled at the downvote and close votes in particular. To me, this appears to be a programmer which comes from a background where you can use `+` to concatenate things to a string, such as in Java for example. @barakmanos I'm fairly sure he is trying to concatenate the number (as a string) to the prefix. – Nicu Stiurca Feb 11 '16 at 16:29
  • 1
    @Rocket As you can see, your intent isn't very clear to everyone. So even though your question has some very good attributes like relevant code snippets and errors you are seeing, people are rather dismissive on account of not being able to figure out your intentions. I recommend making that clearer both in this question and in the future. – Nicu Stiurca Feb 11 '16 at 16:33
  • I've done some PHP scripting, and am now trying to do some simple bits in c++. Thanks for the help and advise. – Rocket Feb 11 '16 at 16:43
  • `ostringstream oss; oss << "/home/user/Download/" << rdn; const string& stl_string_object = oss.str(); const char* null_terminated_string = stl_string_object.c_str(); downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt", null_terminated_string);` – barak manos Feb 11 '16 at 16:45
  • 1
    Thanks for the edit @Rocket. Unfortunately, many SO users are very impatient with questions that are not 100% up to spec. In their defense, most of the rules about what we expect of questions are well thought out, tried, and proven; however, the intent of your broken code was probably very obvious to someone with a PHP background, so I understand why you didn't include it. Point is, don't get discouraged about posting in the future. – Nicu Stiurca Feb 11 '16 at 16:50

2 Answers2

3

If you use c++ 11 you can do

std::string download_location = "/home/user/Download/" + std::to_string(rdn)
downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt", download_location.c_str());

Even better would be to do away with char* and use strings everywhere. It's too easy to introduce errors with char*.

Alternatively you could also use stringstream for generic and efficient string concatenation/formatting.

#include <sstream>
...

stringstream download_location_stream;
download_location_stream << "/home/user/Download" << rdn;

downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt",
             download_location_stream.str().c_str());
Sorin
  • 11,863
  • 22
  • 26
  • I get error to_string not in std, when I try this. – Rocket Feb 11 '16 at 16:43
  • If you do a lot of string concatenation, you may want to consider overloading `operator+` to help you out. `/** append a string with a string-ified T */ template std::string operator+(const std::string &a, const T &b) { return a + std::to_string(b); }` `/*** prepend a string with a string-ified T */ template std::string operator+(const T &a, const std::string &b) { return std::to_string(a) + b; }` Then `std::string("/some/dir/")+rnd` should work. (sorry for bad formatting. Can't answer closed question.) – Nicu Stiurca Feb 11 '16 at 16:51
  • @Rocket You probably don't use a C++11 compiler or disable some of the relevant feature. That's OK, I've added another method that work on older compilers just fine. – Sorin Feb 12 '16 at 09:09
3

as @leemes said, you can use the sprintf:

char str[100];
sprintf(str,"/home/user/Download/%d",rdn);
downloadFile("http://servera.com/file.txt", "/user/tmp/file.txt", str);
AliVar
  • 159
  • 5
  • 2
    Probably better to use `snprintf()` instead of regular `sprintf()` here. – Yam Marcovic Feb 11 '16 at 16:34
  • 2
    For the ~~love of all that is holy~~ hate of nasal demons, please always use `snprintf`. – Nicu Stiurca Feb 11 '16 at 16:34
  • Can you explain the difference between snprintf and sprintf ? Why is there concern for using one over the other ? How do you use snprintf ? This solution is working great for me ! – Rocket Feb 12 '16 at 13:48
  • the string functions (including sprintf, strcmp, strcpy, ...) have a **size** **limit** version. For example snprintf ensures that the size of the resulting string does not exceed the specified size. Its usage is as follows: snprintf(str,99,"/home/user/Download/%d",rdn); Its preference is due to its controlled (and predicted!) behavior :) – AliVar Feb 12 '16 at 15:35