0

I am new to C++ having trouble in assigning value to char* of a function. I have a function as below which returns bool

bool Function(char* inString)
{
        int m = strlen(inString);
    char output[1001];
    memset(output , 0 , sizeof(output));
    sprintf_s(output,50,"length is %d",m);

       if(m>5)
        return true;
    if(m<5) 
        return false;

}

Along with the function , i am trying to get the "output" value on calling this function outside defined local inside this function which has value - "length is -"

I tried doing

 bool Function(char* inString)
{
int m = strlen(inString);
    char output[1001];
    memset(output , 0 , sizeof(output));
    sprintf_s(output,50,"length is %d",m);
    sprintf_s(inString,50,output);
  if(m>5)
            return true;
        if(m<5) 
            return false;
}

But this fails because inString has already a value and this is giving following error Access violation writing location 0x00165267.

Is there any way to get both parameters from this function ( bool value based on string length) as well as b) the string statement "output"?

I appreciate your help..

junni lomo
  • 769
  • 3
  • 10
  • 15

4 Answers4

3

How are you calling this function? If you're calling it with a string literal, then that string literal is likely in read-only memory. For example, this will fail:

bool result = Function( "longer than 5" );

That will likely result in an access violation because the string "longer than 5" is likely in read-only memory. (It's not required to be, but it's likely with modern compilers.)

Also, as Alexandru pointed out above, you didn't handle the m==5 case at all.

Edit: If you want to get the string you're generating with sprintf_s out of the function, you have a couple options.

  1. You could add a second parameter with a buffer to print the string into. Instead of declaring a buffer on the stack (your char output[1001]), you could instead have this pointer passed to you. ie. your function prototype becomes bool Function(char *inString, char *outString);
  2. Make your buffer static, and then return a pointer to it by reference. That requires you to add a second operand. This one is a bit uglier: bool Function(char *inString, char **outString); Then, inside your code you say *outString = output, which is, frankly, gross.
  3. Move your output buffer to a file-scope array. That's even uglier.

One of the advantages of #1 above is that you can use default arguments and an if-statement to make the sprintf optional:

bool Function(char *inString, char *outString = 0)
{
    int m = strlen(inString);

    if (outString)
        sprintf_s(outString, 50, "length is %d", m);

    return m >= 5;
}

Also, a stylistic note: Prefer char *inString to char* inString. In C and C++, the asterisk is not part of the type being declared, but rather a modifier on the individual symbol being declared. If you want to declare two character pointers a and b, you write char *a, *b, not char* a, b.

Edit 2: If you believe John Carmack's insistence that you const anything that could be const, then the above becomes:

bool Function(const char *const inString, char *const outString = 0)
{
    const int m = strlen(inString);

    if (outString)
        sprintf_s(outString, 50, "length is %d", m);

    return m >= 5;
}

I suppose you could go further and make it return const bool, except the function's return value is already an rvalue...

Joe Z
  • 17,413
  • 3
  • 28
  • 39
  • Yeah, most compilers would catch and optimize that. I'll go ahead and edit my answer above, though. – Joe Z Jul 02 '13 at 09:26
  • 1
    If you ever find a compiler that *doesn't* "optimize" that, it's time to throw that compiler away. But Roddy's suggestion isn't a performance optimization, it's a *readability* optimization. – Cody Gray - on strike Jul 02 '13 at 09:28
  • I just find it more readable. Unless you happen to prefer `if ((m>=5) == true) ...` ;-) – Roddy Jul 02 '13 at 09:28
  • @Roddy and @Cody Gray: I agree with you that the more concise form is more readable. I've worked with too many programmers, though, that need the longer, more-spelled-out form, sadly. They get confused when they see you returning a comparison as a value, as if comparisons are only valid inside an `if`, `while` or `for`. This isn't Pascal, folks. – Joe Z Jul 02 '13 at 09:33
  • Awesome! Thats impressive answer. I was exactly looking for this solution. Thanks Joe and everyone! – junni lomo Jul 02 '13 at 09:35
1

To be able to return a string from the function. You need the string to be allocated in such a way that it is alive even after you exit the function. Your example stores the string in a local array(output), which does not live beyond the scope({ }) of the function.

There are several ways to do this:

  • Dynamically allocated memory
  • static storage

and so on, which one to use depends on your usage semantics.

You just need to pass the output string as a function parameter. Since you want to allocate the string inside the function you need to pass a pointer by reference.

On a side note, consider using std::string instead of a char *

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

Since you are using c++ you should do something like

bool Function(std::string &inString, std::string &outString)
{
    size_t size = inString.size();
    outString = "length is " + std::to_string(size); //if c++11
    if (size > 5)
            return true;
    return false;
}

to convert your size_t to string in C++ you can use boost::lexical_cast or this define

#include <sstream>
#define SSTR( x ) dynamic_cast< std::ostringstream & >(( std::ostringstream() << std::dec << x ) ).str()

 inString = "length is " + SSTR(size);
Community
  • 1
  • 1
Alexis
  • 2,149
  • 2
  • 25
  • 39
0

Your code is not really C++, it's C.

Here's how you should do it in C++. Note the use of references rather than pointers.

bool Function(const std::string &inString, std::string &outString)
{
  int m = inString.size();

  std::stringstream ss;
  ss << "length is" << m;

  outString = ss.str();

  return m >= 5;
}
Roddy
  • 66,617
  • 42
  • 165
  • 277