Thread: Stuck halfway through a function

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    28

    Stuck halfway through a function

    Hi all,

    I'm trying to create a function that finds a key=value pair in a file and returns the value part for the given key. EG, if test.conf contains the text "port=10", I need a function to which I can hand "port" and get "10" returned to me.

    I've got this far:-

    Code:
    char * getStringFromConf(char searchkey) {
    	char c[120];
    	FILE *f;
    	f = fopen(CONF_FILE_PATH, "r");
    	while ( fgets(c, 120, f) != NULL ) {
    		char *sep = "=";
    		char *key, *value;
    		key = strtok(c, sep);
    		value = strtok(NULL, sep);
    		}
    	}
    
    	fclose(f);
    }
    ... and the core of this works fine outside of a function (I wrote a quick and dirty test for that).

    I'm unsure where to go from here in terms of matching the key variable with searchkey, and then returning the value variable as an appropriate type.

    Can the experts here help?

    Many thanks.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Your function returns char*, but I see no return.

    Or if you decided to snip for brevity, I bet you're returning a pointer to your local array (or a pointer to somewhere within that array).

    Both of which are wrong.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    And the searchkey argument should likely be a const char *, and you want to compare that to the key read from the file...

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Solution 1: Take 4 arguments, 2 buffers, 2 sizes of buffers.
    Solution 2: Take 2 pointer-to-pointers and allocate enough memory via malloc. The function that calls getStringFromConf will have to free them.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    28
    Your function returns char*, but I see no return.
    Yup, as mentioned I haven't got that far. So taking the above into account:-

    Code:
    char * getStringFromConf(const char * searchkey) {
    	char c[120];
    	FILE *f;
    	f = fopen(CONF_FILE_PATH, "r");
    	while ( fgets(c, 120, f) != NULL ) {
    		char *sep = "=";
    		char *key, *value;
    		key = strtok(c, sep);
    		value = strtok(NULL, sep);
    		}
    	}
    
            if ( strcmp(key, searchkey) == 0 ) {
                  // Got our required value
            }
    	fclose(f);
    }
    Does that look about right? What's the best way for me to store and then return the value?

    Thanks.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    int getStringFromConf(const char * searchkey, char *place_for_result, size_t resultSize );

    The return result is a boolean true / false indicating the success or failure of you trying to read the file.
    If success, you copy what you find to place_for_result, up to at most resultSize characters.

    In that respect, a little bit like how fgets() returns strings to you.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by trillianjedi View Post
    Does that look about right? What's the best way for me to store and then return the value?
    Thanks.
    Quote Originally Posted by Elysia View Post
    Solution 1: Take 4 arguments, 2 buffers, 2 sizes of buffers.
    Solution 2: Take 2 pointer-to-pointers and allocate enough memory via malloc. The function that calls getStringFromConf will have to free them.
    Copy result into the buffers instead of retuning it.
    Pay attention to Salem.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    May 2008
    Posts
    28
    Thanks Salem/Elysia - sorry, I was being slow earlier (late night ).

    Now I have:-

    Code:
    int getStringFromConf(const char * searchkey, char *resultValue, size_t resultSize) {
            int result = 0;
            char c[120];
            FILE *f;
            f = fopen(CONF_FILE_PATH, "r");
            if (f != NULL)  {
    
                    while ( fgets(c, 120, f) != NULL ) {
                            char *sep = "=";
                            char *key, *value;
                            key = strtok(c, sep);
                            value = strtok(NULL, sep);
                            if ( (value != NULL) && (strcmp(key, searchkey) == 0) ) {
                                    //strcpy(resultValue, value); <-- causes a bus error
                                    resultSize = strlen(value);
                                    printf("Value : &#37;s", value);
                                    printf("Size : %d", resultSize);
                                    result = 1;
                            }
                    }
    
                    fclose(f);
    
            } else {
                    result = -1;
            }
                                                                          
            return result;
    }
    But the strcpy I'm trying to do (currently commented out) is causing a bus error. I'm not sure why as I believe the pointer to char is the correct type for it (according to the man page)?

    Thanks...

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    What's the calling code for getStringFromConf?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    May 2008
    Posts
    28
    Ah, you might have just put me on the right track with your question. My test calling app looks like this (header includes removed for brevity):-

    Code:
    int main(void)
    {
    
    char * s;
    size_t i;
    
            if ( getStringFromConf("host", s, i) == 0 ) {
                    printf("&#37;s", s);
            }
    
    return 0;
    
    }
    I guess I need to hand the function a pointer to the searchkey string rather than a string? I'm unclear on the correct syntax here as it's been a long time for me since doing any C.

    I tried declaring a char * key for the key variable and then using strcpy(key, "host") but that's also causing the bus error.

    Thanks for your help so far - it's much appreciated.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, the error is that s is not initialized.
    http://cpwiki.sourceforge.net/A_pointer_on_pointers
    Plus, resultSize is supposed to be the size of the buffer, not an uninitialized value.
    And you can just pass a buffer defined on the stack, along with sizeof(variable).

    Never pass an argument that is uninitialized, unless you are passing its address.
    Uninitialized variables contain garbage and will therefore most likely not make your program work correctly.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    May 2008
    Posts
    28
    Thanks Elysia. Just trying to get my head around this:-

    And you can just pass a buffer defined on the stack, along with sizeof(variable).
    So, something like:-

    char key[20];
    char value[20];

    .... and called as:-

    i = getStringFromConf(&key, &value, sizeof(value))

    ?

    Thanks

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Nay, don't pass an array with &. They are automatically passed as pointers.
    Otherwise it is more correct. Don't forget to check if your buffer is large enough to hold the data before you copy it into the buffer.
    Moreover, you can return the required size or take size as a pointer and update it with the required buffer to hold all the data.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    May 2008
    Posts
    28
    Many thanks - all working now.

    Don't forget to check if your buffer is large enough to hold the data before you copy it into the buffer.
    Right. So I would look at the strlen of value and see if there's enough room in the buffer (plus 1 for the null terminator) before copying.

    If buffer isn't big enough, I understand updating the size_t if I've got a pointer to it, but I'm unclear on how the memory for the buffer is actually allocated? Would I need to allocate that manually ?

    Thanks.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The calling function would have to do something about it. Most likely it would have to dynamically allocate big enough store afterwards.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Needs help in Dev-C++
    By Korrupt Lawz in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2010, 01:17 AM
  2. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  3. doubt in c parser coding
    By akshara.sinha in forum C Programming
    Replies: 4
    Last Post: 12-23-2007, 01:49 PM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM