Variable length equal to value length

showbix
showbix used Ask the Experts™
on
I have a file called puj1.conf which contain these value.
SOCKET_PORT 2001
MODEM_PORT /dev/tty2a1
LOG_FILE puj1.log

My question is, how do I retrieve SOCKET_PORT value, MODEM_PORT value and LOG_FILE value and put it in the variables? I want the variables length as exact as the value length, for example
i.   the variable to store "2001" is length 4
ii.  the variable to store "/dev/tty2a1" is length 11
iii. the variable to store "puj1.log" is length 8

The variable length must follow the value length. This is because the value might change.

Here is my code that I write. Anyone who can suggest me a better idea on doing this is welcome.


--------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
     FILE *config_file;
     char read_line[50];
     char *substr_pos;
     int start_pos;
     char socket_port[10];

     config_file = fopen("puj1.conf", "r");
     while (fgets(read_line, 50, config_file))
     {
          char *search_str = read_line;

          substr_pos = strstr(search_str, "SOCKET_PORT");
          if (substr_pos != NULL)
          {
               start_pos = search_str - substr_pos;
               if (start_pos < 0)
               {
                    start_pos = -start_pos;      
               }

               strncpy(socket_port,search_str+start_pos+9,15);
               /* sometimes the length of socket_port value is less than 15 but unknown character is padding at the back of it to fill the defined length */
               printf("socket_port = %s\n",socket_port);

          }

     }
     fclose(config_file);
     return 0;
}

---------------------------------------------------------
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
When you read a line with fgets it should be NULL terminated so you should be able to use strcpy rather than strncpy.  You can remove any trailing whitespace quite easily and your variables should contain only the data you want.
fridomCEO/Programmer

Commented:
There are quite a few bugs in your code.
you open a file but do not check if you really was able to open it and happily call fgets on a possible NULL pointer.

you use a while fgets loop but do not not check for anything else but SOCKET_PORT, than you try to copy 15 elements in a character array which just has enough space for 10 ELEMENTS with the trailing '0'. You write happily over memory not owned by you.

What do you think is search_str+start_pos+9 supposed to do?

For the size requirements, either you start with a reasonable value which has enough space for all the values, or you have to read the file char by char read it into and array and resize that array if needed. I'm too lazy to implement that so here's simplified solution:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void){
  char * config_file_name = "puj1.conf";
  FILE *config_file = NULL;
  int BUF_SIZE = 128;
  int READ_LINE_SIZE = 256;
  char read_line[READ_LINE_SIZE];
  char fmt_string [READ_LINE_SIZE];
  char val[3][BUF_SIZE];
  char *look_for[3] = {"SOCKET_PORT",                                     "MODEM_PORT",
               "LOG_FILE"};
  int i = 0;
  char *ret_val = NULL;
  int irval = 0;

  config_file = fopen (config_file_name, "r");
  if (config_file == NULL){
     fprintf(stderr, "Could not open %s\n", config_file_name);
          exit (EXIT_FAILURE);
     }

     while (i < 3){
          ret_val = fgets(read_line, READ_LINE_SIZE, config_file);
          if (! ret_val){
               fprintf(stderr, "Could not read line properly, giving up\n");
               exit (EXIT_FAILURE);
          }
          sprintf(fmt_string, "%s %%128s", look_for[i]);
           irval = sscanf(read_line, fmt_string, val[i]);
          if (irval == 1) {
               printf("got value %s\n", val[i]);
          }
          ++i;
     }
     fclose(config_file);
     return 0;
}



After that you got the values in the val array. Now you could go over it and allocate for just enough space as needed. But be aware that I did not remove the trailing \n which is kept in read_line after fgets.

Again that's left to you...

Regards
Friedrich

Author

Commented:
Hi Friedrich.

There are some compilation error on your code.

cc: "fdr.c", line 10: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 11: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 12: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 12: error 1501: Only the first dimension of an array may be omitted.
cc: "fdr.c", line 12: error 1574: Unknown size for "val".
cc: "fdr.c", line 32: error 1720: Subscript expression must combine object pointer and integer.
cc: "fdr.c", line 32: warning 563: Argument #3 is not the correct type.
cc: "fdr.c", line 34: error 1720: Subscript expression must combine object pointer and integer.
cc: "fdr.c", line 34: warning 563: Argument #2 is not the correct type.
*** Error exit code 1
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
Hi Friedrich.

There are some compilation error on your code.

cc: "fdr.c", line 10: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 11: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 12: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 12: error 1501: Only the first dimension of an array may be omitted.
cc: "fdr.c", line 12: error 1574: Unknown size for "val".
cc: "fdr.c", line 32: error 1720: Subscript expression must combine object pointer and integer.
cc: "fdr.c", line 32: warning 563: Argument #3 is not the correct type.
cc: "fdr.c", line 34: error 1720: Subscript expression must combine object pointer and integer.
cc: "fdr.c", line 34: warning 563: Argument #2 is not the correct type.
*** Error exit code 1

Author

Commented:
Hi Friedrich.

There are some compilation error on your code.

cc: "fdr.c", line 10: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 11: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 12: error 1502: Array size must be a constant expression.
cc: "fdr.c", line 12: error 1501: Only the first dimension of an array may be omitted.
cc: "fdr.c", line 12: error 1574: Unknown size for "val".
cc: "fdr.c", line 32: error 1720: Subscript expression must combine object pointer and integer.
cc: "fdr.c", line 32: warning 563: Argument #3 is not the correct type.
cc: "fdr.c", line 34: error 1720: Subscript expression must combine object pointer and integer.
cc: "fdr.c", line 34: warning 563: Argument #2 is not the correct type.
*** Error exit code 1
CEO/Programmer
Commented:
Well well, it seems GCC is much more complieant than what you're using.
Try this instead
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_SIZE 128
#define READ_LINE_SIZE 256


int main (void){
     char * config_file_name = "puj1.conf";
     FILE *config_file = NULL;
     char read_line[READ_LINE_SIZE];
     char fmt_string [READ_LINE_SIZE];
     char val[3][BUF_SIZE];
     char *look_for[3] = {"SOCKET_PORT",
                               "MODEM_PORT",
                               "LOG_FILE"};
     int i = 0;
     char *ret_val = NULL;
     int irval = 0;

     config_file = fopen (config_file_name, "r");
     if (config_file == NULL){
          fprintf(stderr, "Could not open %s\n", config_file_name);
          exit (EXIT_FAILURE);
     }

     while (i < 3){
          ret_val = fgets(read_line, READ_LINE_SIZE, config_file);
          if (! ret_val){
               fprintf(stderr, "Could not read line properly, giving up\n");
               exit (EXIT_FAILURE);
          }
          sprintf(fmt_string, "%s %%128s", look_for[i]);
           irval = sscanf(read_line, fmt_string, val[i]);
          if (irval == 1) {
               printf("got value %s\n", val[i]);
          }
          ++i;
     }
     fclose(config_file);
     return 0;
}

Author

Commented:
Thanks Friedrich. It works.
But how do I remove "\n" in the string after using strcat()?
fridomCEO/Programmer

Commented:
See my posting to you other question.

check out the manual pages for strchr

Regards
Friedrich

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial