C Strings not returning from a function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pkirk25

    #1

    C Strings not returning from a function

    I've made a small program to demonstrate one problem I'm having fixing
    strings in C.

    I need to be able to remove HTML mark-ups from text lines.

    I create my variable, pass it to my function, verify that the data has
    been passed correctly and then cannot get the data back!

    If I change the return to some random string literal, it comes back
    fine.

    All advice appreciated.

    #include <stdio.h>
    #include <string.h>

    char * FixString(char *strIn)
    {
    char *strMsg = strIn;
    char strTmp[40] = "";
    char *strReturn = &strTmp;

    int i = 0;
    int j = strlen(strMsg);


    for (i = 0; i <= j; ++i)
    {
    /* removing the cleanup code for brevity on usenet */
    strTmp[i] = strMsg[i];
    }

    printf("%s\n", strReturn);
    /* Prints out the string perfectly */

    return strReturn; /* change to return "All clear" and it works fine
    */
    }

    int main(void)
    {
    char *strOut = "This is a line from a web page <br>";
    char *strBack = FixString(strOu t);

    printf("%s\n", strBack); /* Prints garbage - why? */

    return 0;
    }

  • Ian Collins

    #2
    Re: C Strings not returning from a function

    pkirk25 wrote:
    I've made a small program to demonstrate one problem I'm having fixing
    strings in C.
    >
    I need to be able to remove HTML mark-ups from text lines.
    >
    I create my variable, pass it to my function, verify that the data has
    been passed correctly and then cannot get the data back!
    >
    If I change the return to some random string literal, it comes back
    fine.
    >
    All advice appreciated.
    >
    #include <stdio.h>
    #include <string.h>
    >
    char * FixString(char *strIn)
    {
    char *strMsg = strIn;
    char strTmp[40] = "";
    char *strReturn = &strTmp;
    >
    Didn't your compiler give you a helpful diagnostic here? If not, turn
    up its warning level or use a better compiler.
    int i = 0;
    int j = strlen(strMsg);
    >
    >
    for (i = 0; i <= j; ++i)
    {
    /* removing the cleanup code for brevity on usenet */
    strTmp[i] = strMsg[i];
    }
    >
    printf("%s\n", strReturn);
    /* Prints out the string perfectly */
    >
    return strReturn; /* change to return "All clear" and it works fine
    You are attempting to return a pointer to a local variable, don't do
    this. Either pass in the output string, or use a dynamic buffer
    allocated by the function and return this.

    --
    Ian Collins.

    Comment

    • pkirk25

      #3
      Re: C Strings not returning from a function

      [snip]
      My complier is Visual C++ 6 wcih I know is old but it is what was
      available.

      I genuinely think my problems are dwon to struggling with indirection
      and pointers moret han the compiler, tempting tho it is to blame
      Microsoft.
      >
      You are attempting to return a pointer to a local variable, don't do
      this. Either pass in the output string, or use a dynamic buffer
      allocated by the function and return this.
      Ian, if i retrun the string array strTmp that *strReturn points to, I
      get the same mess.

      Can you explain what you mean by "pass in the output string"? What
      would I change in my code to do that? Sorry to ask to be spoon fed.

      Comment

      • Ian Collins

        #4
        Re: C Strings not returning from a function

        pkirk25 wrote:
        [snip]
        My complier is Visual C++ 6 wcih I know is old but it is what was
        available.
        >
        I genuinely think my problems are dwon to struggling with indirection
        and pointers moret han the compiler, tempting tho it is to blame
        Microsoft.
        >
        A C++ compiler should refuse to compile the line you snipped;

        char *strReturn = &strTmp;

        Here you are attempting to initialise a char* with a char**, either use

        char *strReturn = strTmp;

        or

        char *strReturn = &strTmp[0];
        >>You are attempting to return a pointer to a local variable, don't do
        >>this. Either pass in the output string, or use a dynamic buffer
        >>allocated by the function and return this.
        >
        >
        Ian, if i retrun the string array strTmp that *strReturn points to, I
        get the same mess.
        >
        Can you explain what you mean by "pass in the output string"? What
        would I change in my code to do that? Sorry to ask to be spoon fed.
        >
        Add an extra parameter:

        char* FixString( const char* strIn, char* strOut )

        Note the change of strIn to const, you aren't changing it in your
        function. Use strOut where you use strTmp.

        You can then call it with:

        const char *strOut = "This is a line from a web page <br>"

        char *backBuff = char[someSize];

        char *strBack = FixString(strOu t, backBuff);

        --
        Ian Collins.

        Comment

        • pkirk25

          #5
          Re: C Strings not returning from a function

          Code almsot half the size and works perfectly.

          Thanks!

          BTW, the complier warns that malloc returns int and that my *backBuff
          is not one in the line:

          char *backBuff = malloc(i);

          If I fix that, no more VC++ warnings.


          #include <stdio.h>
          #include <string.h>

          char * FixString(char *strIn, char *strOut)
          {
          int i = 0;
          int j = strlen(strIn);


          for (i = 0; i <= j; ++i)
          {
          /* removing the cleanup code for brevity on usenet */
          strOut[i] = strIn[i];
          }

          printf("%s\n", strOut);


          return strOut;
          }

          int main(void)
          {
          char *strOut = "This is a line from a web page <br>";
          int i = strlen(strOut);
          char *backBuff = malloc(i);
          char *strBack = FixString(strOu t, backBuff);

          printf("%s\n", strBack); /* Prints out the string perfectly */

          return 0;
          }

          Comment

          • Ian Collins

            #6
            Re: C Strings not returning from a function

            pkirk25 wrote:
            Code almsot half the size and works perfectly.
            >
            Please keep some context in your replies.
            Thanks!
            >
            BTW, the complier warns that malloc returns int and that my *backBuff
            is not one in the line:
            >
            That's because you haven't included the required header, <stdlib.h>

            --
            Ian Collins.

            Comment

            • pkirk25

              #7
              Re: C Strings not returning from a function

              "0 error(s), 0 warning(s)"

              Well, that means i can go to bed!

              Thanks and good night.

              Comment

              • Ian Collins

                #8
                Re: C Strings not returning from a function

                pkirk25 wrote:
                "0 error(s), 0 warning(s)"
                >
                Well, that means i can go to bed!
                >
                Thanks and good night.
                >
                Didn't you see my comment about context?

                --
                Ian Collins.

                Comment

                • Keith Thompson

                  #9
                  Re: C Strings not returning from a function

                  Ian Collins <ian-news@hotmail.co mwrites:
                  pkirk25 wrote:
                  >[snip]
                  >My complier is Visual C++ 6 wcih I know is old but it is what was
                  >available.
                  >>
                  >I genuinely think my problems are dwon to struggling with indirection
                  >and pointers moret han the compiler, tempting tho it is to blame
                  >Microsoft.
                  >>
                  A C++ compiler should refuse to compile the line you snipped;
                  >
                  char *strReturn = &strTmp;
                  >
                  Here you are attempting to initialise a char* with a char**, either use
                  >
                  char *strReturn = strTmp;
                  >
                  or
                  >
                  char *strReturn = &strTmp[0];
                  A C compiler should refuse to compile it.

                  Actually, that's not quite true. Attempting to initialize a char*
                  with a char** is a constraint violation. A conforming C compiler must
                  issue a diagnostic. Once it's done so, it's not required either to
                  accept or to reject the translation unit.

                  <OT>I *think* the rules are similar in C++, but I'm too lazy to search
                  through the C++ standard for the corresponding wording. In any case,
                  I *think* that Visual C++ can be used as a C compiler.</OT>

                  --
                  Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                  San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                  We must do something. This is something. Therefore, we must do this.

                  Comment

                  • Ian Collins

                    #10
                    Re: C Strings not returning from a function

                    Keith Thompson wrote:
                    Ian Collins <ian-news@hotmail.co mwrites:
                    >>
                    >>A C++ compiler should refuse to compile the line you snipped;
                    >
                    A C compiler should refuse to compile it.
                    >
                    Actually, that's not quite true. Attempting to initialize a char*
                    with a char** is a constraint violation. A conforming C compiler must
                    issue a diagnostic. Once it's done so, it's not required either to
                    accept or to reject the translation unit.
                    >
                    <OT>I *think* the rules are similar in C++, but I'm too lazy to search
                    through the C++ standard for the corresponding wording. In any case,
                    I *think* that Visual C++ can be used as a C compiler.</OT>
                    >
                    <OT>In C++, you can't assign or initialise with incompatible types, it's
                    an error.</OT>

                    I can't see why C doesn't enforce the same rules, if you want to do an
                    incompatible assignment, you can force the issue with a cast.

                    --
                    Ian Collins.

                    Comment

                    • Ian Collins

                      #11
                      Re: C Strings not returning from a function

                      Ian Collins wrote:
                      pkirk25 wrote:
                      >
                      >>[snip]
                      >>My complier is Visual C++ 6 wcih I know is old but it is what was
                      >>available.
                      >>
                      >>I genuinely think my problems are dwon to struggling with indirection
                      >>and pointers moret han the compiler, tempting tho it is to blame
                      >>Microsoft.
                      >>
                      >
                      A C++ compiler should refuse to compile the line you snipped;
                      >
                      char *strReturn = &strTmp;
                      >
                      Here you are attempting to initialise a char* with a char**, either use
                      >
                      Oops, I should have written "attempting to initialise a char* with a
                      pointer to an array of char".

                      --
                      Ian Collins.

                      Comment

                      • CBFalconer

                        #12
                        Re: C Strings not returning from a function

                        pkirk25 wrote:
                        >
                        .... snip ...
                        >
                        I create my variable, pass it to my function, verify that the data
                        has been passed correctly and then cannot get the data back!
                        >
                        If I change the return to some random string literal, it comes
                        back fine.
                        >
                        All advice appreciated.
                        >
                        #include <stdio.h>
                        #include <string.h>
                        >
                        char * FixString(char *strIn)
                        {
                        char *strMsg = strIn;
                        char strTmp[40] = "";
                        char *strReturn = &strTmp;
                        >
                        .... snip ...
                        >
                        return strReturn; /* change to return "All clear" and it works fine
                        */
                        You are returning the address of local storage, which storage no
                        longer exists after the function returns. Change the prototype to
                        read:

                        void FixString(const char *strIn, char *strOut, sizet maxout);

                        and call it with

                        char *instring = "whatever";
                        char outstring[SZ]; /* where SZ has been suitably defined */

                        FixString(instr ing, outstring, SZ-1);

                        remembering that the parameters instring and outstring will
                        automatically be converted to pointers to the first member at the
                        call. You can use the maxout parameter to protect against buffer
                        overflow. You can also change the void type to int if you need to
                        return an error indicator (such as incipient buffer overflow).
                        --
                        Some informative links:
                        <news:news.anno unce.newusers
                        <http://www.geocities.c om/nnqweb/>
                        <http://www.catb.org/~esr/faqs/smart-questions.html>
                        <http://www.caliburn.nl/topposting.html >
                        <http://www.netmeister. org/news/learn2quote.htm l>
                        <http://cfaj.freeshell. org/google/>

                        Comment

                        • Barry Schwarz

                          #13
                          Re: C Strings not returning from a function

                          On Tue, 26 Sep 2006 10:46:28 +1200, Ian Collins <ian-news@hotmail.co m>
                          wrote:
                          >pkirk25 wrote:
                          >[snip]
                          >My complier is Visual C++ 6 wcih I know is old but it is what was
                          >available.
                          >>
                          >I genuinely think my problems are dwon to struggling with indirection
                          >and pointers moret han the compiler, tempting tho it is to blame
                          >Microsoft.
                          >>
                          >A C++ compiler should refuse to compile the line you snipped;
                          >
                          >char *strReturn = &strTmp;
                          >
                          >Here you are attempting to initialise a char* with a char**, either use
                          The advice is correct but the detail is wrong. The statement attempts
                          to assign a char* with a value of type char(*)[40].
                          >
                          >char *strReturn = strTmp;
                          >
                          >or
                          >
                          >char *strReturn = &strTmp[0];
                          >
                          snip


                          Remove del for email

                          Comment

                          • Keith Thompson

                            #14
                            Re: C Strings not returning from a function

                            Ian Collins <ian-news@hotmail.co mwrites:
                            Keith Thompson wrote:
                            >Ian Collins <ian-news@hotmail.co mwrites:
                            >>>
                            >>>A C++ compiler should refuse to compile the line you snipped;
                            >>
                            >A C compiler should refuse to compile it.
                            >>
                            >Actually, that's not quite true. Attempting to initialize a char*
                            >with a char** is a constraint violation. A conforming C compiler must
                            >issue a diagnostic. Once it's done so, it's not required either to
                            >accept or to reject the translation unit.
                            >>
                            ><OT>I *think* the rules are similar in C++, but I'm too lazy to search
                            >through the C++ standard for the corresponding wording. In any case,
                            >I *think* that Visual C++ can be used as a C compiler.</OT>
                            >>
                            <OT>In C++, you can't assign or initialise with incompatible types, it's
                            an error.</OT>
                            >
                            I can't see why C doesn't enforce the same rules, if you want to do an
                            incompatible assignment, you can force the issue with a cast.
                            C does enforce the same rules. An assignment between incompatible
                            types is a constraint violation, requiring a diagnostic.

                            A C compiler is never required to *reject* a translation unit unless
                            it contains a "#error" directive. (Many implementation-specific
                            extensions are implemented by giving meaning to code that would
                            otherwise violate a constraint.)

                            --
                            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                            San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                            We must do something. This is something. Therefore, we must do this.

                            Comment

                            • Ian Collins

                              #15
                              Re: C Strings not returning from a function

                              Barry Schwarz wrote:
                              On Tue, 26 Sep 2006 10:46:28 +1200, Ian Collins <ian-news@hotmail.co m>
                              wrote:
                              >
                              >
                              >>pkirk25 wrote:
                              >>
                              >>>[snip]
                              >>>My complier is Visual C++ 6 wcih I know is old but it is what was
                              >>>available.
                              >>>
                              >>>I genuinely think my problems are dwon to struggling with indirection
                              >>>and pointers moret han the compiler, tempting tho it is to blame
                              >>>Microsoft.
                              >>>
                              >>
                              >>A C++ compiler should refuse to compile the line you snipped;
                              >>
                              >>char *strReturn = &strTmp;
                              >>
                              >>Here you are attempting to initialise a char* with a char**, either use
                              >
                              >
                              The advice is correct but the detail is wrong. The statement attempts
                              to assign a char* with a value of type char(*)[40].
                              >
                              I know, that's why I corrected it.

                              --
                              Ian Collins.

                              Comment

                              Working...