Thread: Beginner: malloc and array of strings

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    14

    Beginner: malloc and array of strings

    I would like to read a conf file and put parameters of my configuration in some variables. But when I parse file and put parameters to array of strings (that I would like to use in rest of programm) and try to print those strings (for testing purposes) I have garbage...
    I think that I have problem allocating memory for array of string and need your help understanding how things works .....

    Here is the code that doesn't work:
    -------------------------------------------------
    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXSTRING 256
    #define comment '#'
    #define conffile "backup.conf"
    #define logfile "backup.log"
    //////////////////////////////////////////////////////////////
    ////// Log file procedure ///////////////////////////////////
    //////////////////////////////////////////////////////////////
    void log_message(char * m_essage1,char * m_essage2)
    {
    FILE *f_ile;
    f_ile=fopen(logfile,"w+");
    if(f_ile==NULL)
    {
    printf("Error: can't open log file!\n");
    exit(1);
    }
    time_t t=time(NULL);
    char *t_ime=ctime(&t);
    fprintf(f_ile,"%-s | %-s %-s\n",t_ime,m_essage1,m_essage2);
    fclose(f_ile);
    return 0;
    }
    
    
    /////////////////////////////////////////////
    //////////// MAIN ///////////////////////////
    /////////////////////////////////////////////
    int main()
    {
    char _buff_in[MAXSTRING];
    char **_param;
    int str_nos=20; //No of strings you want to have
    int str_len=256; //Maximum length of each string
    _param=calloc( str_nos,sizeof(char *) );
    if(_param == NULL )
    {
    log_message("Error: calloc _param.","");
    exit(1);
    }
    int k;
    for(k=0;k<str_nos;k++)
    {
    _param[k]=calloc( str_len,sizeof(char *) );
    if(_param[k] == NULL )
    {
    log_message("Error: calloc _param[k].","");
    exit(1);
    }
    }
    FILE *fp;
    if ( (fp = fopen(conffile, "r")) == NULL)
    {
    log_message( "Error: Opening backup.conf.\n","");
    exit(1);
    }
    int i=0;
    while (!feof(fp))
    {
    fgets(&_buff_in, MAXSTRING, fp );
    if((strchr(&_buff_in,comment))==NULL)
    {
    sscanf(&_buff_in,"%*s %*s %256[^\n]c",&_param[i]);
    printf("%s\n",&_param[i]);
    i++;
    }
    }
    fclose(fp);
    int j;
    puts("--------------------------");
    for(j=0;j<i;j++)
    {
    printf("%s\n",&_param[j]);
    free(_param[j]);
    }
    free(_param);
    return 0;
    }
    --------------------------------------------

    HERE IS MY CONF FILE:
    --------------------------------------------
    #OS = Linux
    OS = Windows
    #
    #
    NUMB_DIF_EXT = 15
    #
    #
    #EXT = .trc
    EXT = .log;.trc
    #
    #
    #MULTIPLE_FILES = YES
    MULTIPLE_FILES = NO
    #
    #
    #ARCHIVE = .tar
    ARCHIVE = .zip
    #
    #
    #SOURCE = /usr/home/docs
    SOURCE = C:\Documents and Settings\Default User\Desktop
    #
    #
    #INCLUDE_SUBFOLDERS = NO
    INCLUDE_SUBFOLDERS = YES
    #
    #
    #DESTINATION = /usr/home/backup
    DESTINATION = D:\docs\CodeBlocks\Backup
    ---------------------------------------------------

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    1)
    Code:
    f_ile=fopen(logfile,"w+");
    Everytime you open the logfile with "w+", the old content is lost. If you want to append to the file you should use "a".

    2)
    Code:
    for(k=0;k<str_nos;k++)
    {
    _param[k]=calloc( str_len,sizeof(char *) );
    You want to allocate memory for "str_len" characters (each one byte), but you allocate room for "str_len" pointers to char (each probably 4 bytes).

    3)
    Code:
    while (!feof(fp))
    FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com

    4)
    Code:
    fgets(&_buff_in, MAXSTRING, fp );
    if((strchr(&_buff_in,comment))==NULL)
    {
    sscanf(&_buff_in,"%*s %*s %256[^\n]c",&_param[i]);
    printf("%s\n",&_param[i]);
    "_buff" and "_param[i] are already pointers, so there is no need to use the &-operator. You should get warnings if you compile with all warnings turned on.
    And the 'c' at the end of the format string of sscanf() doesn't do what you probably think it should do. If you want to catch the newline at the end of the line you would need to replace it with "%*c" (assuming you don't want to store it). But it's not really necessary to take care about it, so just ignore it.

    FYI: To avoid using the magic number (256) in your format string you could use the following trick:
    Code:
    #define MAX 10
    #define STR(x) #x
    #define MACRO_TO_STR(x) STR(x)
    ...
    scanf("%" MACRO_TO_STR(MAX) "[^\n]", string_variable);
    // the above line will be rewritten by the preprocessor to 
    scanf("%" "10" "[^\n]", string_variable);  // adjacent strings are concatenated by the compiler
    (See also Question 11.17)

    5)
    Code:
    printf("%s\n",&_param[j]);
    Same as 4).

    6)
    Why do you use an underscore in front of or in between your variable names (e.g. "_param", "f_ile", "m_essage1")?

    Bye, Andreas
    Last edited by AndiPersti; 03-18-2013 at 06:11 AM.

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    14
    1) I know for a+, but want new file everytime I start program so I can easily debug ... not scrolling down to look for last logs ...
    2) Yes, you are right it should be sizeof(char) instead sizeof(char *)
    3) Good point, thank you !
    4) and 5) - After I have removed & it worked correctly. Yes, it is already a pointer.
    6) IDE informs about usage of system commands, names, variables .... but just to avoid possibility to have overlaping with those. Any suggestion what convention to use for naming variables, arrays, functions ?
    FYI) I am working on it now !!!!

    Thank you very much.

  4. #4
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    f_ile is not a very good variable name imo. You can find lots of info about code naming conventions and formatting with a web search. For my part here are a few things i follow:

    constants ALL_CAPS and using underscores where required
    I dont like underscores in other frequently referenced data
    simple and complex datatypes camelCase with first letter lower case
    function names CamelCase with first letter upper case
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    14
    Not sure about "scanf("%""10""[^\n]", string_variable);"
    As result I have first 10 characters from string. what I want is:
    string: OS = Windows
    string_variable=Windows
    So, I need to remove "OS" and "=" and space characters.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Even worse, you have a couple of identifiers that start with an underscore. Such identifiers are reserved by the C standard for use by the implementation. Using them causes your code to exhibit undefined behaviour.

    (Strictly speaking, there are a couple of exceptions to this guideline since the actual clauses in the standard are a bit more involved. But explaining the actual rules to a beginner is an effective way to make a beginner's head spin. Hence, with beginners, I fall back on the guideline of "don't do that!").
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Quote Originally Posted by 0ooo0 View Post
    Not sure about "scanf("%""10""[^\n]", string_variable);"
    As result I have first 10 characters from string. what I want is:
    string: OS = Windows
    string_variable=Windows
    So, I need to remove "OS" and "=" and space characters.
    I've shown you just an example usage. You have to adapt it for your program. Basically you would just need to modify your original sscanf()-call from line 64 (remove the magic number and add the macro).

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can strings fit in an array? (2 beginner questions)
    By Rubik in forum C Programming
    Replies: 6
    Last Post: 03-06-2013, 01:12 AM
  2. Beginner casting and malloc/realloc question!
    By klawson88 in forum C Programming
    Replies: 14
    Last Post: 10-07-2010, 12:21 PM
  3. beginner: dynamic array of strings
    By pc2-brazil in forum C++ Programming
    Replies: 10
    Last Post: 04-29-2008, 04:29 PM
  4. how to use malloc for array of strings
    By SoFarAway in forum C Programming
    Replies: 3
    Last Post: 02-18-2005, 04:19 PM
  5. malloc() strings VS array strings
    By Kleid-0 in forum C Programming
    Replies: 5
    Last Post: 01-10-2005, 10:26 PM