Thread: passing strings from functions as the "return" part

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    11

    passing strings from functions as the "return" part

    Hi all, I am a beginner to C. The following is not a completed program, or even a part of a program, but I see no point in writing any more before I can get this to compile...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int get_filename();
    
    int main(void){
    
    
    
    //declarations
        FILE    *input_stream;
      
    //program statements
        input_stream = fopen( get_filename(), "r" ) ); //line 37
             //there will be error checking here, in the form of an if, eventually
        }
    
    int get_filename(){
    
    //declarations
        char filename[101];
    
    //program statements
        printf("enter filename:   ");
        scanf( "%s", filename);
        return (filename); //line 47
        
        }
    The problem is already obvious to you guys, but I am getting the following errors:

    37 passing arg 1 of `fopen' from incompatible pointer type
    37 syntax error before ')' token
    In function `get_filename':
    47 [Warning] return makes integer from pointer without a cast
    47 [Warning] function returns address of local variable


    To me this appears to be basically one error, that manifests in several places. I think it is to do with the returning of the contents of the variable filename. Of course, I could just put it in main, but that would be like giving up, and I will need to know how to do this in the future, anyway. Can you return strings out of functions like that? I have tried the FAQ and everything, to no avail....any ideas?

    Thanks in advance...

    fraktal

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    First of all, your function says it returns an int, but you are trying to return a pointer to a char. Secondly, the array you allocated goes out of scode when the function returns. The way this is usually done, is you pass the string buffer into the function like so:

    Code:
    void get_filename(char *filename){
    
        printf("enter filename:   ");
        fflush(stdout);  // you should put this line here
        scanf( "%s", filename);
        
    }
    Note that the above code can cause a buffer overflow error if the user inputs a string that is longer than the space you allocated for the file name. The correct way to avoid this would be to pass the size of the buffer to the get_filename function, and use fgets() to get the user input, or some other input function that checks buffer sizes. To use the above code, you would do:

    Code:
    char filename[100];
    get_filename(filename);
    printf("User entered %s\n",filename);

  3. #3
    Registered User
    Join Date
    Dec 2005
    Posts
    11
    That's fantastic. Thanks a lot. There are still one or two things I don't understand though, and I would be very grateful if you could explain them to me?
    Firstly, could you explain what you meant by
    "the array you allocated goes out of scode when the function returns"
    ..because I don't understand what that means at all.

    Secondly, maybe I missed something, but i thought that functions couldn't alter variables when they are returned back to main (for example, if you set x=1 in main, and then set x++ in a function, even after running the function x would always stay as 1 in main) so how does main acquire the value of filename in the following code:
    Code:
        get_filename(filename);
        printf( "%s", filename);
        system("pause");
        return(0);
        }
    
    int get_filename(char *ffile){
        printf("enter filename:   ");
        fflush (stdout);
        scanf( "%s", ffile);
        return (&ffile);
        }
    if it had said filename=get_filename(filename) then that would make sense, because you are storing the return value from the function. Although, even if I replace return (&ffile) with return(0) the program functions the same, which implies that the return value isn't used anyway.(nb..all variables have been declared above.)

    Third (this is quick, I promise) you will notice that I replaced return (ffile) with return (&ffile) ...this solves the compiler error of returning an integer without a cast, but is this correct code or have I just fiddled with it until the compiler shuts up?

    I know I am asking a lot of questions, but I don't see the point of using code without knowing what it is doing, if I do that I don't learn anything. Thans very much for your help.
    Last edited by fraktal; 12-12-2005 at 04:57 AM. Reason: changed the name of the variable inside the function for clarity

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by fraktal
    That's fantastic. Thanks a lot. There are still one or two things I don't understand though, and I would be very grateful if you could explain them to me?
    Firstly, could you explain what you meant by
    "the array you allocated goes out of scode when the function returns"
    ..because I don't understand what that means at all.
    What he is saying is that this:
    Code:
    char filename[101];
    is declared locally in the function get_filename. Since it is not a static type array, when the function ends, *poof*, it's gone.

    Quote Originally Posted by fraktal
    Secondly, maybe I missed something, but i thought that functions couldn't alter variables when they are returned back to main (for example, if you set x=1 in main, and then set x++ in a function, even after running the function x would always stay as 1 in main) so how does main acquire the value of filename in the following code:
    Code:
        get_filename(filename);
        printf( "%s", filename);
        system("pause");
        return(0);
        }
    When you use the name of an array in this particular context, you get what amounts to this:

    Code:
    get_filename(filename);
    ...is really like doing this:

    Code:
    get_filename(&filename[0]);
    When you use the array name in that particular context, it evalutes to the address of the first element of that array, ie., &array[0].

    So then, you are passing the address of the array, and any work done on it in the called function is reflected on the actual array back in main.



    Quote Originally Posted by fraktal
    Third (this is quick, I promise) you will notice that I replaced return (filename) with return (&filename) ...this solves the compiler error of returning an integer without a cast, but is this correct code or have I just fiddled with it until the compiler shuts up?

    I know I am asking a lot of questions, but I don't see the point of using code without knowing what it is doing, if I do that I don't learn anything. Thans very much for your help.
    You have indeed fiddled with it until the compiler shuts up, but it is probably not going to do what you wanted.
    Last edited by kermit; 12-12-2005 at 05:13 AM.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    11
    Right, I see. It makes sense now. Unfortunately, I think I am likely to encounter more problems further down the line. Until then, thanks very much, you have been extremely helpful. I am very grateful.

  6. #6
    Registered User
    Join Date
    Dec 2005
    Posts
    11

    sscanf not writing to struct pointer-things

    okay, sorry to keep coming back, but I really can't see what's wrong with my code here.
    I have progressed somewhat since my last posts. I have written a program that implements linked lists before, but now with very similar code in this program I can't get it to work. The problem i'm having is with sscanf, I will include the relevant part of my code:
    Code:
            struct rootnode{
                float gauge_diameter;
                float gauge_length;
                float force;
                float extension;
                struct node *nextnodeaddr;
                } *node1_addr;
    
            node1_addr = malloc( sizeof(struct rootnode) );
    
            fgets(  line, sizeof(line), input_stream  );
            sscanf(  line, "%s %lf", null, &node1_addr->gauge_diameter);
            printf(  "\nread: %s %lf\n",       null,
            node1_addr->gauge_diameter);
    all variables have been declared. line is a character string containing the ascii string:
    Gauge_diameter: 20.0e-3 m.
    The output on the screen is read: Gauge_diameter: 89128.960938 which is obviously wrong. The thing is, when I use the workaround
    Code:
            sscanf(  line, "%s %lf", null, gauge_diameter);
            node1_addr->gauge_diameter=gauge_diameter;
    where gauge_diameter is declared as a float, of course, the answer is right, which suggests that the problem is the way the struct is shown to sscanf. Any ideas?


    Thanks again

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    %lf expects a pointer to a double, you have a pointer to a float.

    Are you using gcc for your compiler?

  8. #8
    Registered User
    Join Date
    Dec 2005
    Posts
    11
    oh yeah! I fixed that, and it all works fine now. I don't know what I was using "float" for...Thanks a lot!

    (by the way: yes, I am using gcc.)

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    gcc -W -Wall -ansi -pedantic -O2 prog.c
    Will diagnose an awful lot of problems, including mis-matches between the format string and parameters of printf and scanf type functions.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing arrays of pointers into functions
    By ashley in forum C Programming
    Replies: 5
    Last Post: 01-13-2007, 06:48 PM
  2. functions and passing data
    By redmondtab in forum C Programming
    Replies: 41
    Last Post: 09-21-2006, 12:04 PM
  3. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM
  4. Passing structures between functions
    By TankCDR in forum C++ Programming
    Replies: 2
    Last Post: 01-29-2002, 10:54 AM
  5. Replies: 1
    Last Post: 01-20-2002, 11:50 AM