4

So, I need to access a .ini file like:

[alpha]
colour=green
size=78
style=italic
[beta]
colour=black
size=94
mode=xyz
[gamma]
black=0231
blue=127
red=0x35876f

I need to find a section [likethis], then a parameter (one of the follow three) and then return its value. So, section alpha, param size, I return "78". Section gamma, param red, I return "0x35876f". section beta, param red doesn't exist.

char *sFile: Name of file
char *sSec:  Section where the parameter is
char *sPar:  Parametro wanted
char *sRet:  Array where I store the value
int  ilen:  Lenght of the array

i open the file with fp = fopen (sFile,"r");, but then it gets complicated to find and return the value and I dont know if this is the best way to do it.

char *strAux, *strAux2;

while(!feof(fp)) //While the file doesnt end
{
    fscanf (fp,"%s",strAux); //Read a line of the file
    if(!strcmp(strAux,sSec)) //If I found the section
    {
        for(j=0; j<3; j++)
        {
            fscanf(fp,"%s",strAux); //Read a line
            strAux2 = strtok (strAux,"="); //store the param in strAux2 from the start to the =
            if (!strcmp(strAux2,sPar))
            {
                strAux2 = strtok (NULL,"\r\n"); //store in strAux2 frmo the = to end of line
                if(strlen(strAux2)>ilen)
                {
                    fclose(fp);
                    return (-3);  //Error, Lenght Value > ilen
                }else{
                    strncpy(sRet,strAux2,ilen);
                    fclose(fp);
                    return (sRet);   //Return the value
                }
            }
        }
    }           
}
fclose(fp);
return (-2);  //Error, Parameter not found

Is this ok?

rockstiff
  • 355
  • 1
  • 2
  • 17
  • 1
    "I" is with SHIFT on English! No, NO NO "i"! – peterh Mar 02 '15 at 01:50
  • See [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) for a discussion of why your code is dubious from the start. You must check the return value from `fscanf()` before you try using the `strAux` variable. And you need to allocate memory to read the string into. – Jonathan Leffler Mar 02 '15 at 04:16
  • 1
    Your function returns a `char *` on success but various negative numbers on failure. That is, at best, an icky interface. You'd do better always returning an integer — 0 on success and negative on failure. Since `sRet` appears to be an input parameter to the function, there's no need to return it to indicate success. – Jonathan Leffler Mar 02 '15 at 04:20

2 Answers2

1

I think a more manual approach is easier

open the file

search lines starting with [

when done look for a line with the param name and a = (If you find a [ search has failed)

extra skip space around '='

FILE *f = fopen("test.ini", "r");                                          
char *sSec = "beta";                                                       
char *sPar = "size";                                                       
char *sRet = NULL;                                                         
char *p;                                                                   
char buf[1024];                                                            
bool section_search = true;                                                

while (p = fgets(buf, 1024, f)) {                                          
    if (section_search) {                                                  
        const char *q = sSec;                                              
        if (*p != '[') {                                                   
            continue;                                                      
        }                                                                  
        p++; /* read [ */                                                  
        while (*q && *p == *q) {                                           
            p++;                                                           
            q++;                                                           
        }                                                                  
        if (*q == '\0' && *p == ']') {                                     
            section_search = false;                                        
            continue;                                                      
        }                                                                  
    } else {                                                               
        const char *q = sPar;                                              

        if (*p == '[') {                                                   
            break;                                                         
        }                                                                  
        while (*q && *p == *q) {                                           
            p++;                                                           
            q++;                                                           
        }                                                                  
        if (*q != '\0')                                                    
            continue;                                                      
        while (*p == ' ') p++;                                             
        if (*p != '=')                                                     
            continue;                                                      
        p++; /*read =*/                                                    
        while (*p == ' ') p++;                                             
        sRet = p;                                                          
        break;                                                             

    }                                                                      
}                                                                          
if (sRet) {                                                                
    printf("value found %s", sRet);                                        
} else {                                                                   
    printf("value not found");                                             
}   
Ôrel
  • 7,044
  • 3
  • 27
  • 46
  • I you need to search several values, think about load the ini in memory and search into your struct can be improve with hashtable or trie – Ôrel Mar 02 '15 at 03:14
  • How can you read more values, like size and colour for example? I have tried so much to change the code but it doesn't work :( – Bianca Balan Aug 21 '21 at 08:51
  • @BiancaBalan perhaps you can parse the conf into hash tables and then search on the hash tables. – Ôrel Aug 21 '21 at 13:36
0

Dont use while(!feof). Instead you could use while(fscanf(fp,"%s",buf) ==1) and you can use same token delimiter for strtok for both the calls as =. You should allocate memory for strAux before using it in fscanf.

Sridhar Nagarajan
  • 1,085
  • 6
  • 14