0

For any function that is declared to take a char* output parameter, is there a way to specify the "char" part of s std::string as the function's output?

I began with:

// EDIT:  ADDED THESE TWO LINES FOR CLARITY

sprintf(buf, "top -n 1 -p %s" , commaSeparatedListOfPIDs.c_str() );
fp = popen(buf, "r");

std::string  replyStr;
char         reply[100];

rc = scanf( fp, "%s", reply );
replyStr = reply;

but that seems a bit, well, clumsy.

So, is there a way to say:

rc = scanf( fp, "%s", &replyStr.c_str() );

or something like that?

Thanks!

Wes Miller
  • 2,191
  • 2
  • 38
  • 64
  • possible duplicate of [Does the address of the result of std::string::operator\[\] point to a writable, nul-terminated buffer?](http://stackoverflow.com/questions/9728450/does-the-address-of-the-result-of-stdstringoperator-point-to-a-writable-n) – ildjarn Apr 25 '12 at 23:23
  • I see I missed an important point, the fd is from a popen(). – Wes Miller Apr 26 '12 at 00:09

5 Answers5

2

Yes this is possible:

std::string  replyStr(100, '\0');
//Requires C++11 (to guarantee that strings hold their characters
//in contiguous memory), and some way to ensure that the string in the file
//is less than 100 characters long.
rc = fscanf( fp, "%s", &reply.front() );
replyStr.erase(replyStr.find('\0'));

The second condition is very difficult to satisfy, and if it is not satisfied this program has undefined behaviour.

Mankarse
  • 39,818
  • 11
  • 97
  • 141
  • In my case, since I'm stealing from **top**, I know the max linesize is < 100. – Wes Miller Apr 26 '12 at 11:37
  • Boy was I wrong. From **man top**: The width of top's display will be limited to 512 positions. Displaying all fields requires a minimum of 160 characters. The remaining width could be used for the 'Command' column. c/100/512/ – Wes Miller Apr 26 '12 at 11:50
1

Up until c++0x, &str[0] wasn't required to return a pointer to contiguous storage. The conventional way would be to use std::vector, which is guaranteed to have contiguous storage even before c++0x:

std::vector<char> reply(100);
rc = scanf(fp, "%s", &reply[0]);

In c++0x, however, std::string is also guaranteed to work instead of std::vector.

kalev
  • 1,925
  • 1
  • 15
  • 12
  • But std::vector won't have all those substring and size and whatever else properties as would a std::string. The methods would apply to the collection, not the collected. – Wes Miller Apr 26 '12 at 11:35
0

If you want to use strings, why not use the C++ way of i/o as well? Take a look at this link

Mads
  • 724
  • 3
  • 10
0

std::string replyStr(reply); will make a string of your char array.

EDIT:

but... that doesn't do anything different.

Use the c++ style in/out to not have to use char*.

cin >> replyStr; will get the next string until whitespace. getline(cin,reply); will set the string to an entire line of input

Sam Sussman
  • 1,005
  • 8
  • 27
0

The char* that comes from std::String is only valid as long as the string is valid. If the std::String goes out of scope then the it is no longer a valid char pointer.

const char* bar;
{
    std::String foo = "Hello";
    bar = foo.c_str();
    printf("%s", bar); //SAFE since the String foo is still in scope
}
printf("%s", bar); //UNSAFE String foo is no longer in scope

As long as the std::String variable exists you can use the const char* if it goes out of scope the memory is released and the const char* pointer becomes a dangling pointer that is no longer safe to use.

if you need it to exist after the std::String foo has gone out of scope then you must copy the string into a char*

char bar[100];
{
    std::String foo = "Hello";
    strncpy(bar, foo.c_str(), 100);
    bar[100] = '\0'; //make sure string is null-terminated
    printf("%s", bar); //SAFE
}
printf("%s", bar); //SAFE even though the std::String has gone out of scope.

If your string is inside a function it will not exist when the function returns.

gnash117
  • 1,025
  • 1
  • 13
  • 24
  • Sorry, but foo here is an input to the function. I want foo as an output. The sort of thing where the parameter is the address of the variable such that the function can reply into that variable. – Wes Miller Apr 26 '12 at 11:33