The overall best solution to where to store strings is to do it in the same way that most string functions do, and that is make the caller supply the storage of where the string is to be stored. You already use fgets() as a prime example of this technique, so use the same idea
Like so.
Code:
/*
* About, a program for reading information
* from a configuration file.
* By Joel Glidden,
*/
#include<stdio.h>
#include<string.h>
char *cfgOption(char *optionKey, FILE *cfgFile, char *optionValue, size_t optionLen);
int main()
{
FILE *cfgFile;
char *myName;
char optionValue[20];
cfgFile = fopen("about.conf", "r");
myName = cfgOption("UserName: ", cfgFile, optionValue, sizeof(optionValue) );
printf("My name is %s.\n", myName);
printf("My name is %s.\n", optionValue); /* Same thing */
fclose(cfgFile);
return 0;
}
/*
* You could make it more like fgets(), by say returning NULL if optionKey
* isn't found in the file.
*/
char *cfgOption(char *optionKey, FILE *cfgFile, char *optionValue, size_t optionLen)
{
char buff[BUFSIZ];
size_t Keylen = strlen(optionKey);
optionValue[0] = '\0'; /* just in case nothing is found */
while( fgets(buff, sizeof buff, cfgFile) != NULL)
{
char *nl = strchr( buff, '\n' ); /* find a newline */
if ( nl != NULL ) *nl = '\0'; /* remove it if necessary */
if ( strncmp( buff, optionKey, Keylen ) == 0 )
{
/* copy to user store, but don't overflow if it won't fit */
strncpy( optionValue, &buff[Keylen], optionLen );
optionValue[optionLen-1] = '\0';
break;
}
}
rewind(cfgFile);
return optionValue; /* this is OK, it was a parameter after all */
}