Passing and returning arrays to and from functions

Discussion in 'C Programming' started by Pete, Sep 17, 2004.

  1. Pete

    Pete Guest

    Can someone please help, I'm trying to pass an array to a function, do some
    operation on that array, then return it for further use. The errors I am
    getting for the following code are, differences in levels of indirection, so
    I feel it must have something to do with the way I am representing the array
    in the call and the return.

    Below I have commented the problem parts.

    Thanks in advance for any help offered.
    Pete

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

    char P10(char key[]); /* prototype */

    void main()
    {

    char key[20];
    int i;

    printf("\nEnter a 10 bit Binary Sting: ");
    gets(key); /* Copy representation of 10 bit binary string
    entered from keyboard to key[]. "not to use for binary operations
    just representation */

    /* below I'm getting an error 'char[]' differs in levels of indirection to
    'char'
    and '=' left operand must be l-value */

    key = P10(key); /* function call. copy returned array into key[] */
    printf("Key is now : \n");
    for(i=0; i<10; ++i) { /* loop to print returned array key[] */
    printf("%c\n", key);
    }
    }


    char P10(char Ctext[]) { /* Trivial function to permute input string */

    int Perm10[10]={3,5,2,7,4,10,1,9,8,6};
    int i;
    int index;

    /* Trace statement checking key[] has been passed */
    for(i=0;i<10;++i) {
    printf("Ctext = %c\n", Ctext);
    }
    /* Trivial Permutation function */
    for(i=0; i<10; i++) {
    index = Perm10;
    printf("index = %d\n", index);
    Ctext = Perm10[index-1];


    }
    /* Below shows the error 'return' : 'char' differs in
    levels of indirection from 'char *' */

    return Ctext; /* return Ctext[]/key[] to calling function */
    }
     
    Pete, Sep 17, 2004
    #1
    1. Advertising

  2. Pete

    Malcolm Guest

    "Pete" <> wrote
    > #include <stdio.h>
    > #include <string.h>
    >
    > char P10(char key[]); /* prototype */
    >

    This is right but it suggests misunderstanding.
    >
    > void main()
    >

    This should be int main() to be ANSI-compliant.
    >
    > {
    >
    > char key[20];
    > int i;
    >
    > printf("\nEnter a 10 bit Binary Sting: ");
    > gets(key); /* Copy representation of 10 bit binary string
    > entered from keyboard to key[]. "not to use for binary operations
    > just representation */
    >

    gets() is OK for a test program, but not for real code, because you will
    corrupt memory if someone type in more than 19 characters (19 + NUL)
    >
    > /* below I'm getting an error 'char[]' differs in levels of indirection to
    > 'char'
    > and '=' left operand must be l-value */
    >
    > key = P10(key); /* function call. copy returned array into key[] */
    >

    This is where the misunderstanding creeps in.
    >
    > printf("Key is now : \n");
    > for(i=0; i<10; ++i) { /* loop to print returned array key[] */
    > printf("%c\n", key);
    > }
    > }
    >
    >
    > char P10(char Ctext[]) { /* Trivial function to permute input string */
    >
    > int Perm10[10]={3,5,2,7,4,10,1,9,8,6};
    > int i;
    > int index;
    >
    > /* Trace statement checking key[] has been passed */
    > for(i=0;i<10;++i) {
    > printf("Ctext = %c\n", Ctext);
    > }
    > /* Trivial Permutation function */
    > for(i=0; i<10; i++) {
    > index = Perm10;
    > printf("index = %d\n", index);
    > Ctext = Perm10[index-1];
    >
    >
    > }
    > /* Below shows the error 'return' : 'char' differs in
    > levels of indirection from 'char *' */
    >
    > return Ctext; /* return Ctext[]/key[] to calling function */
    > }
    >


    The first point is that most C primers introduce multi-dimensional arrays at
    about the same time as one-dimensional arrays. This is IMO a mistake. In C,
    one-dimensional arrays are basic, but multi-dimensional arrays are advanced
    features.

    What does this have to do with you, since you only use a 1 dimensional
    array?

    The answer is that the primer obscures the truth that C does not pass or
    return arrays to functions. It passes the address of the first element of
    the array.

    Your function should therefore be

    char P10(char *Ctext)

    However virtually any programmer would want some security about the length
    of the array (and not just rely on the caller reading the comments and
    guessing from the name that P10 takes 10 characters)

    So the prototype becomes

    /*
    P2 - permute an array
    Ctext - text to permute
    N - length of text ( must be 10 in current version)
    */
    char P10(char *Ctext, int N)

    Now since we are passing a pointer to the array, the array will be permuted
    in place. There is thus no need to return anything. So the function becomes

    void P2(char *Ctext, int N)

    However let's say you do not want to modify the array passed. What do we do
    then? The answer is

    void P2(const char *Ctext, int N, char *output)

    If you are going to allow Ctext and output to be the same, you will have to
    code carefully.
     
    Malcolm, Sep 17, 2004
    #2
    1. Advertising

  3. Pete

    Jack Klein Guest

    On Fri, 17 Sep 2004 12:08:12 +1000, "Pete" <> wrote in
    comp.lang.c:

    > Can someone please help, I'm trying to pass an array to a function, do some
    > operation on that array, then return it for further use. The errors I am
    > getting for the following code are, differences in levels of indirection, so
    > I feel it must have something to do with the way I am representing the array
    > in the call and the return.


    That's because you can't pass or return bare arrays to or from
    functions.

    > Below I have commented the problem parts.
    >
    > Thanks in advance for any help offered.
    > Pete
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > char P10(char key[]); /* prototype */


    This prototype is exactly equivalent to:

    char P10(char *key);

    ....because the name of an array is always converted to a pointer to
    its first element when used as an argument to a function. C allows
    the notation that you used as a synonym to the one that I used. I
    really wished that had never been allowed, because it only adds to the
    array/pointer confusion that many newbies have.

    And even if you could return an array from a function, which you
    can't, you have prototyped a function with a return type of a single
    char only.

    Actually, you want to change the return type of this function to void,
    see my comments in the function itself.

    > void main()


    This is a problem part that you neglected to comment. The only
    standard, portable return type for main() in a hosted C environment is
    'int'. No matter what the illiterate help files for some compilers
    say.

    int main()

    ....or even better:

    int main(void)

    > {
    >
    > char key[20];
    > int i;
    >
    > printf("\nEnter a 10 bit Binary Sting: ");
    > gets(key); /* Copy representation of 10 bit binary string


    Here's another problem that you didn't comment. Any, any, ANY use of
    the function gets() is a defect. It is the only function in the
    standard C library that can NEVER be used safely, and most especially
    NOT TO BE used for interactive user input.

    What do you think will happen is a user types 40 or 50 characters
    before pressing enter, and gets() tries to put them all in your 20
    character string? Bad things will happen.

    > entered from keyboard to key[]. "not to use for binary operations
    > just representation */
    >
    > /* below I'm getting an error 'char[]' differs in levels of indirection to
    > 'char'
    > and '=' left operand must be l-value */
    >
    > key = P10(key); /* function call. copy returned array into key[] */


    Right, you can't assign to an array like 'key', or any other array for
    that matter.

    Fortunately, you don't need to. When you pass 'key' to P10, that
    function will actually receive a pointer to key[0]. Any change it
    makes to key[0] and other characters via the pointer it receives
    change the contents of the original array. So you don't need to
    return it, it just changes as the function runs.

    So make this:

    P10(key);

    > printf("Key is now : \n");
    > for(i=0; i<10; ++i) { /* loop to print returned array key[] */
    > printf("%c\n", key);
    > }


    ....and since you are going to fix your source to properly define
    main() as returning an int, add this here:

    return 0;
    > }
    >
    >
    > char P10(char Ctext[]) { /* Trivial function to permute input string */


    Change to:

    void P10(char Ctext[])

    ....or even better to help avoid confusion in the future:

    void P10(char *Ctext)

    > int Perm10[10]={3,5,2,7,4,10,1,9,8,6};
    > int i;
    > int index;
    >
    > /* Trace statement checking key[] has been passed */
    > for(i=0;i<10;++i) {
    > printf("Ctext = %c\n", Ctext);
    > }
    > /* Trivial Permutation function */
    > for(i=0; i<10; i++) {
    > index = Perm10;
    > printf("index = %d\n", index);
    > Ctext = Perm10[index-1];
    >
    >
    > }
    > /* Below shows the error 'return' : 'char' differs in
    > levels of indirection from 'char *' */


    The body of this function above here actually does what you want it to
    do, because even though P10 receives Ctext as a pointer to char, you
    can use subscripting on a pointer.

    > return Ctext; /* return Ctext[]/key[] to calling function */


    Since this is now a function returning 'void', just omit this line.

    > }


    Run, do not walk, to the FAQ for this group, link in my signature, and
    read all of the entire section on pointers and arrays.

    Then get a good C book, such as "The C Programming Language, Second
    Edition" by Kernighan & Ritchie.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Sep 17, 2004
    #3
  4. Pete

    Michael Mair Guest

    Hello,

    > However let's say you do not want to modify the array passed. What do we do
    > then? The answer is
    >
    > void P2(const char *Ctext, int N, char *output)


    size_t N is not only nicer but even makes most sense when using char
    arrays... :)

    > If you are going to allow Ctext and output to be the same, you will have to
    > code carefully.


    Spell it out: The actual "permutation function" provided by the OP
    is crap. I reordered the posting and comment on it now:

    I enter with Ctext[]="1111110000";

    >>char P10(char Ctext[]) { /* Trivial function to permute input string */
    >>
    >>int Perm10[10]={3,5,2,7,4,10,1,9,8,6};
    >>int i;
    >>int index;
    >>
    >>/* Trace statement checking key[] has been passed */
    >>for(i=0;i<10;++i) {
    >>printf("Ctext = %c\n", Ctext);
    >>}
    >>/* Trivial Permutation function */
    >> for(i=0; i<10; i++) {
    >> index = Perm10;

    i=0: index=3;
    >> printf("index = %d\n", index);
    >> Ctext = Perm10[index-1];

    Ctext[0]=Perm10[3-1]=2;
    There was never a two in the original Ctext.
    >>
    >>
    >> }
    >>/* Below shows the error 'return' : 'char' differs in
    >> levels of indirection from 'char *' */
    >>
    >> return Ctext; /* return Ctext[]/key[] to calling function */
    >> }


    I am not sure what this is to mean. I think it should have been
    something along the lines
    Ctext=Ctext[index-1];
    However, this is crap, too: Imagine the very simple permutation
    {3,1,2} working on {'0','0','1'}. This gives us the outcome:
    Ctext[0]=Ctext[3-1]; /*='1';*/
    Ctext[1]=Ctext[1-1]; /*='1';*/
    Ctext[2]=Ctext[2-1]; /*='1';*/
    Either you break up your permutation in a series of permutations
    of two values and perform an exchange using an intermediate
    variable:
    /* Perm: {{3,2},{1,2}} */
    temp=Ctext[3-1]; Ctext[3-1]=Ctext[2-1]; /*='0';*/
    Ctext[2-1]=temp; /*='1';*/
    temp=Ctext[1-1]; Ctext[1-1]=Ctext[2-1]; /*='1';*/
    Ctext[2-1]=temp; /*='0';*/
    or you use a temporary array to which you write the
    outcome of your permutations. After that, you copy your
    temporary values into the original array:
    tempArr=Ctext[index-1];
    in your original loop effects tempArr holding the right permutation
    of Ctext. Before returning, do
    for (i=0; i<10; i++)
    Ctext = tempArr;

    Try to wrap your mind arround the ideas of zero-based arrays and
    zero-based permutations to get rid of the "-1".


    Cheers
    Michael
     
    Michael Mair, Sep 17, 2004
    #4
  5. Pete

    John Bode Guest

    "Pete" <> wrote in message news:<414a4996$>...
    > Can someone please help, I'm trying to pass an array to a function, do some
    > operation on that array, then return it for further use. The errors I am
    > getting for the following code are, differences in levels of indirection, so
    > I feel it must have something to do with the way I am representing the array
    > in the call and the return.
    >
    > Below I have commented the problem parts.
    >
    > Thanks in advance for any help offered.
    > Pete
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > char P10(char key[]); /* prototype */
    >


    As Jack explained, "char key[]" in this context is synonymous with
    "char *key"; in both cases, what you're actually passing to the
    function is a pointer to the first element in the array, not a copy of
    the array itself. Among other things, this means that you can't
    automatically determine how many elements are in the array. When
    passing an array argument, it's always good practice to pass the array
    size (number of elements) as a separate argument, e.g.

    char P10 (char *key, size_t keycount);

    > void main()


    On a compliant, hosted implementation, this should be

    int main (void)

    > {
    >
    > char key[20];
    > int i;
    >
    > printf("\nEnter a 10 bit Binary Sting: ");
    > gets(key); /* Copy representation of 10 bit binary string
    > entered from keyboard to key[]. "not to use for binary operations
    > just representation */
    >


    Never ever ever *EVER* use gets(). It *will* introduce a point of
    failure in your program. Use fgets() instead:

    fgets (key, sizeof key, stdin);

    fgets() behaves slightly differently from gets() -- for example, if
    you're entering data from the keyboard and hit Return, fgets() will
    attempt to store that newline character to the target buffer if
    there's room. The lines below will strip out the newline character if
    it's present:

    if (strchr (key, '\n'))
    *(strchr (key, '\n')) = 0;

    If the newline character isn't present, then you know that the user
    typed a string longer than what you're sized to store.

    > /* below I'm getting an error 'char[]' differs in levels of indirection to
    > 'char'
    > and '=' left operand must be l-value */
    >
    > key = P10(key); /* function call. copy returned array into key[] */


    First problem is that you have your function typed to return char
    (single character) and you're attempting to assign that result to an
    array of char (key). Second problem is that you cannot assign values
    to an array identifier directly.

    Since you are writing your results to the array parameter, there's no
    reason to return the array value (functions cannot return array values
    directly anyway).

    Change the function so that it returns "void" (i.e., no value), and
    pass the array size as a parameter, like so:

    P10 (key, sizeof key);

    Also remember to change the prototype above.

    > printf("Key is now : \n");
    > for(i=0; i<10; ++i) { /* loop to print returned array key[] */
    > printf("%c\n", key);
    > }
    > }
    >
    >
    > char P10(char Ctext[]) { /* Trivial function to permute input string */
    >


    void P10 (char *Ctext, size_t CtextSize)

    > int Perm10[10]={3,5,2,7,4,10,1,9,8,6};
    > int i;
    > int index;
    >
    > /* Trace statement checking key[] has been passed */
    > for(i=0;i<10;++i) {


    for (i = 0; i < 10 && i < CtextSize; i++) {

    > printf("Ctext = %c\n", Ctext);
    > }
    > /* Trivial Permutation function */
    > for(i=0; i<10; i++) {
    > index = Perm10;
    > printf("index = %d\n", index);
    > Ctext = Perm10[index-1];
    >
    >
    > }
    > /* Below shows the error 'return' : 'char' differs in
    > levels of indirection from 'char *' */
    >
    > return Ctext; /* return Ctext[]/key[] to calling function */


    Again, this is because you typed the function to return char, but
    you're attempting to return a value that's type char *. Type the
    function to return void and remove the return statement completely.

    > }
     
    John Bode, Sep 17, 2004
    #5
  6. Pete

    Malcolm Guest

    "John Bode" <> wrote offered.
    >
    > > printf("\nEnter a 10 bit Binary Sting: ");
    > > gets(key); /* Copy representation of 10 bit binary string
    > > entered from keyboard to key[]. "not to use for binary

    operations
    > > just representation */
    > >

    >
    > Never ever ever *EVER* use gets(). It *will* introduce a point of
    > failure in your program. Use fgets() instead:
    >
    > fgets (key, sizeof key, stdin);
    >
    > fgets() behaves slightly differently from gets() -- for example, if
    > you're entering data from the keyboard and hit Return, fgets() will
    > attempt to store that newline character to the target buffer if
    > there's room. The lines below will strip out the newline character if
    > it's present:
    >
    > if (strchr (key, '\n'))
    > *(strchr (key, '\n')) = 0;
    >
    >

    No, no, no.
    These lines are an error.
    Think about it, what will happen on overflow?

    Replacing undefined behaviour with wrong behaviour is not an improvement.
    >
    > If the newline character isn't present, then you know that the user
    > typed a string longer than what you're sized to store.
    >

    So to use fgets() you need to check for the newline, and if it is not
    present print out an error message such as "line too long", and then gobble
    the rest of the input.
     
    Malcolm, Sep 17, 2004
    #6
  7. Pete

    John Bode Guest

    "Malcolm" <> wrote in message news:<cif7cm$moc$>...
    > "John Bode" <> wrote offered.
    > >
    > > > printf("\nEnter a 10 bit Binary Sting: ");
    > > > gets(key); /* Copy representation of 10 bit binary string
    > > > entered from keyboard to key[]. "not to use for binary

    > operations
    > > > just representation */
    > > >

    > >
    > > Never ever ever *EVER* use gets(). It *will* introduce a point of
    > > failure in your program. Use fgets() instead:
    > >
    > > fgets (key, sizeof key, stdin);
    > >
    > > fgets() behaves slightly differently from gets() -- for example, if
    > > you're entering data from the keyboard and hit Return, fgets() will
    > > attempt to store that newline character to the target buffer if
    > > there's room. The lines below will strip out the newline character if
    > > it's present:
    > >
    > > if (strchr (key, '\n'))
    > > *(strchr (key, '\n')) = 0;
    > >
    > >

    > No, no, no.
    > These lines are an error.
    > Think about it, what will happen on overflow?
    >


    What overflow?

    > Replacing undefined behaviour with wrong behaviour is not an improvement.
    > >
    > > If the newline character isn't present, then you know that the user
    > > typed a string longer than what you're sized to store.
    > >

    > So to use fgets() you need to check for the newline, and if it is not
    > present print out an error message such as "line too long", and then gobble
    > the rest of the input.


    Or, alternately, store what's been read so far to a larger (preferably
    extendable) buffer and repeat the operation until a newline (or EOF)
    is seen, then work on the target buffer.
     
    John Bode, Sep 21, 2004
    #7
  8. Pete

    Malcolm Guest

    "John Bode" <> wrote
    >
    > > > fgets (key, sizeof key, stdin);
    > > >
    > > > if (strchr (key, '\n'))
    > > > *(strchr (key, '\n')) = 0;
    > > >
    > > >

    > > No, no, no.
    > > These lines are an error.
    > > Think about it, what will happen on overflow?
    > >

    >
    > What overflow?
    >

    If the line the user enters is longer than sizeof key, what will happen?
    What fatal mistake are you making in these three lines?
    >
     
    Malcolm, Sep 21, 2004
    #8
  9. Pete

    John Bode Guest

    "Malcolm" <> wrote in message news:<cipqlk$gs0$>...
    > "John Bode" <> wrote
    > >
    > > > > fgets (key, sizeof key, stdin);
    > > > >
    > > > > if (strchr (key, '\n'))
    > > > > *(strchr (key, '\n')) = 0;
    > > > >
    > > > >
    > > > No, no, no.
    > > > These lines are an error.
    > > > Think about it, what will happen on overflow?
    > > >

    > >
    > > What overflow?
    > >

    > If the line the user enters is longer than sizeof key, what will happen?


    fgets() will read sizeof key-1 characters, write them to key along
    with a terminating null character, and the remaining characters will
    remain in standard input.

    Remember, I'm using _f_gets() instead of gets().

    If no newline character is found in key, strchr(key, '\n') returns
    NULL, so the branch *(strchr (key, '\n')) = 0 isn't taken.

    > What fatal mistake are you making in these three lines?


    Why don't you tell me?

    I *have* tested this, you know. But, if you need convincing:

    [root@rh170 other]# cat key.c
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    int main (void)
    {
    char key[10];

    printf ("sockitome: ");
    fflush (stdout);

    fgets (key, sizeof key, stdin);
    if (strchr(key, '\n'))
    *(strchr(key, '\n')) = 0;

    printf ("key = %s\n", key);

    return 0;
    }

    [root@rh170 other]# gcc -o key -ansi -pedantic -Wall key.c
    [root@rh170 other]# ./key
    sockitome: blurga
    key = blurga
    [root@rh170 other]# ./key
    sockitome: Supercalifragilisticexpealidocious
    key = Supercali
    [root@rh170 other]#

    Did it yak when I typed in more characters than key was sized to hold?
    No. The leftover characters in standard input need to be dealt with,
    but that's a separate problem.

    I freely admit that under most circumstances I *should* be checking
    the result of fgets() for NULL, but for the purposes of this
    demonstration I didn't think it necessary.
     
    John Bode, Sep 21, 2004
    #9
  10. Pete

    Malcolm Guest

    "John Bode" <> wrote
    >
    > I *have* tested this, you know. But, if you need convincing:
    >
    > [root@rh170 other]# cat key.c
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    >
    > int main (void)
    > {
    > char key[10];
    >
    > printf ("sockitome: ");
    > fflush (stdout);
    >
    > fgets (key, sizeof key, stdin);
    > if (strchr(key, '\n'))
    > *(strchr(key, '\n')) = 0;
    >
    > printf ("key = %s\n", key);
    >
    > return 0;
    > }
    >
    > Did it yak when I typed in more characters than key was sized to hold?
    > No. The leftover characters in standard input need to be dealt with,
    > but that's a separate problem.
    >

    The mistake is to think that getting rid of undefined behaviour solves all
    your problems.
    It gives the wrong result on overflow, and by throwing away the newline you
    make it impossible to know if the user typed a whole line or not.
    >

    Now you can say, "in this case we always take the first nine characters, so
    in fact throwing away the newline is OK". This is why no compiler can ever
    catch wrong behaviour, as opposed to undefined behaviour. In fact for an
    interactive program just truncating is very unlikely to be acceptable - the
    user needs to know why a portion of his entry is missing - and even for an
    automated system it is hardly conceivable that you wouldn't want to know if
    fed an overlong key.
     
    Malcolm, Sep 22, 2004
    #10
  11. Pete

    John F. Bode Guest

    On Wed, 22 Sep 2004 06:19:01 +0100, "Malcolm"
    <> wrote:

    >
    >"John Bode" <> wrote
    >>
    >> I *have* tested this, you know. But, if you need convincing:
    >>
    >> [root@rh170 other]# cat key.c
    >> #include <stdio.h>
    >> #include <string.h>
    >> #include <stdlib.h>
    >>
    >> int main (void)
    >> {
    >> char key[10];
    >>
    >> printf ("sockitome: ");
    >> fflush (stdout);
    >>
    >> fgets (key, sizeof key, stdin);
    >> if (strchr(key, '\n'))
    >> *(strchr(key, '\n')) = 0;
    >>
    >> printf ("key = %s\n", key);
    >>
    >> return 0;
    >> }
    >>
    >> Did it yak when I typed in more characters than key was sized to hold?
    >> No. The leftover characters in standard input need to be dealt with,
    >> but that's a separate problem.
    >>

    >The mistake is to think that getting rid of undefined behaviour solves all
    >your problems.
    >It gives the wrong result on overflow, and by throwing away the newline you
    >make it impossible to know if the user typed a whole line or not.


    I'm sorry. In my original response I made the point that unlike
    gets(), fgets() saves the newline (if present) to the target buffer,
    and demonstrated one method for removing it. It was not meant to be a
    comprehensive tutorial on how to use fgets() to handle all situations.
    I believe I said something about dealing with characters remaining in
    standard input, and how that was a separate issue.

    You took three lines out of context and started yammering about
    overflow and fatal errors, which I took to mean a core dump. Excuse
    me for not getting your point right away; next time, say what you
    mean.

    But if you want something a little more comprehensive (if untested):

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

    #define START_SIZE 80

    char *nextInputLine (FILE *stream)
    {
    char *targetBuf = NULL;
    char *r = NULL;
    size_t bufsize = 0;
    char readBuf[START_SIZE+1];
    int gotNewline = 0;

    targetBuf = malloc (START_SIZE+1);
    if (!targetBuf)
    return NULL;

    *targetBuf = 0;
    bufsize = START_SIZE;

    while ((r = fgets(readBuf, sizeof readBuf, stream)) != NULL &&
    !gotNewline)
    {
    if (bufsize - strlen (targetBuf) < strlen (readBuf))
    {
    char *tmp = realloc (targetBuf, bufsize + strlen (readBuf)
    + 1);
    if (tmp)
    {
    targetBuf = tmp;
    bufsize += strlen (targetBuf) + 1;
    }
    else
    {
    printf ("Fatal error: unable to extend target
    buffer\n");
    free (targetBuf);
    return NULL;
    }
    }

    if (strchr (readBuf, '\n'))
    {
    *(strchr (readBuf, '\n')) = 0;
    gotNewline = 1;
    }
    strcat (targetBuf, readBuf);
    }

    if (ferror (stream))
    {
    printf ("Error occured on input stream; line may be
    incomplete\n");
    }
    return targetBuf;
    }

    This *should* handle input lines of arbitrary length (as I said, it's
    untested). Happy?

    >>

    >Now you can say, "in this case we always take the first nine characters, so
    >in fact throwing away the newline is OK". This is why no compiler can ever
    >catch wrong behaviour, as opposed to undefined behaviour. In fact for an
    >interactive program just truncating is very unlikely to be acceptable - the
    >user needs to know why a portion of his entry is missing - and even for an
    >automated system it is hardly conceivable that you wouldn't want to know if
    >fed an overlong key.
    >
     
    John F. Bode, Sep 22, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexandra Stehman
    Replies:
    5
    Views:
    30,687
    Chris Smith
    Jun 17, 2004
  2. Victor Bazarov
    Replies:
    25
    Views:
    903
    E. Robert Tisdale
    Mar 23, 2005
  3. James
    Replies:
    7
    Views:
    320
    James
    Nov 5, 2006
  4. S.
    Replies:
    7
    Views:
    298
    David Thompson
    May 12, 2008
  5. Philipp
    Replies:
    21
    Views:
    1,140
    Philipp
    Jan 20, 2009
Loading...

Share This Page