Thread: Reading an unkown number of ints/doubles/etc.. into variables.

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    4

    Reading an unkown number of ints/doubles/etc.. into variables.

    Hi yea I'm trying to write programs that can read an undeclared ammount of data and assign it into the respective variables. I've been using fgets and sscanf in the past to read and assign variables but i don't know how within sscanf to allow for an unknown number of variables. Any help with sscanf would be great or another function that might preform the job better, I know using strtok might be usefull but I was I wanted to know if there was another was sinec strtok was kind of confusing to me. Thanks for the help in the past and any future help, its much appreciated.

    -Spiros

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Well, it kind of depends on what kind of format the data being read is in. Are the types at least known? Can the data all be thrown into an array or does each value have to have its own variable (impossible)?

    If you're just looking to store each value in a string like "13:27:8:41:75" but you don't know beforehand how many values there are it's pretty simple.
    Code:
    itsme:~/C$ cat vals.c
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(void)
    {
      char *string = "13:27:8:41:75", *p = string;
      int *vals = NULL, nvals = 0;
      int i;
    
      do
      {
        if(*p)
        {
          if(*p == ':')
            p++;
    
          // Should check to make sure memory was allocated successfully
          if(nvals)
            vals = realloc(vals, sizeof(int)*(nvals+1));
          else
            vals = malloc(sizeof(int));
    
          vals[nvals++] = atoi(p);
        }
      } while((p = strchr(p, ':')));
    
      for(i = 0;i < nvals;++i)
        printf("%d\n", vals[i]);
    
      free(vals);
      return 0;
    }
    itsme:~/C$ ./vals
    13
    27
    8
    41
    75
    itsme:~/C$

  3. #3
    ~viaxd() viaxd's Avatar
    Join Date
    Aug 2003
    Posts
    246
    itsme86, your solution is correct, however, if there is a very large amount of data, then it is not efficient to call realloc on every iteration, it would be better to call realloc for a block of elements but then again this will work if their type is known in advance.
    :wq

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You don't need the if(nvals) for a special case, realloc already knows to call malloc directly if the first parameter is NULL

    You also have the realloc bug
    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.

  5. #5
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    It's not a bug if I don't care about trying to save the data in case of failure

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    Quote Originally Posted by itsme86
    It's not a bug if I don't care about trying to save the data in case of failure
    Yet it is a bug if realloc does fail and you dereference the pointer, such as in the following line.
    Code:
    vals[nvals++] = atoi(p);

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    That's why I have that comment in there that says the return value should be checked to see if the allocation was successful. Obviously if the check failed then I wouldn't try using the memory any longer.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Princeton
    Yet it is a bug if realloc does fail and you dereference the pointer, such as in the following line.
    Code:
    vals[nvals++] = atoi(p);
    Thanks to your further illustration, NOW they've discovered it.

    [edit]
    Quote Originally Posted by itsme86
    That's why I have that comment in there that says the return value should be checked to see if the allocation was successful. Obviously if the check failed then I wouldn't try using the memory any longer.
    Shoulda, woulda, coulda, didn't. IF you had actually checked... But you didn't.
    [/edit]

    Quzah
    Last edited by quzah; 08-03-2004 at 07:48 AM.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    >>That's why I have that comment in there that says the return value should be checked
    A comment does not do much good when the program is running.

  10. #10
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(void)
    {
      char *string = "13:27:8:41:75", *p = string;
      int *vals = NULL, nvals = 0;
      int i;
    
      do
      {
        if(*p)
        {
          if(*p == ':')
            p++;
    
          if(!(vals = realloc(vals, sizeof(int)*(nvals+1))))
          {
            puts("Unable to allocate memory");
            exit(1);
          }
    
          vals[nvals++] = atoi(p);
        }
      } while((p = strchr(p, ':')));
    
      for(i = 0;i < nvals;++i)
        printf("%d\n", vals[i]);
    
      free(vals);
      return 0;
    }
    Are we happy now? Sheesh :P

    EDIT: And if you give me the line that NULL doesn't necessarily mean 0 I'll cry :P

  11. #11
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    >>And if you give me the line that NULL doesn't necessarily mean 0 I'll cry :P
    If I said that then I would be wrong.

  12. #12
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by Princeton
    >>And if you give me the line that NULL doesn't necessarily mean 0 I'll cry :P
    If I said that then I would be wrong.
    The language definition states that for each pointer type, there is a special value -- the "null pointer" -- which is distinguishable from all other pointer values and which is not the address of any object or function.
    I don't believe the standard explicitly states that it has to be 0. NULL can be any value as long as it meets the above criteria. But this might be from an old standard.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by itsme86
    I don't believe the standard explicitly states that it has to be 0. NULL can be any value as long as it meets the above criteria. But this might be from an old standard.
    C: A reference Manual; 5th ed. Page 138

    Every pointer type in C has a special value called a null pointer, which is different from every valid pointer of that type, which compares qual to a null pointer constant, which converts to the null pointers of other pointer types, and which has the value "false" when used in a boolean context. The null pointer constant in C is any integer constant expression with the value 0, or such an expression cast to type void *.
    C: A reference Manual; 5th ed. Page 325

    The value of the macro NULL is the traditional null pointer constant. Many implementations define it to be simply the integer constant 0 or 0 cast to type void *.
    Coloration and possible typos mine, otherwise quoted directly.

    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    Jul 2004
    Posts
    101
    >>I don't believe the standard explicitly states that it has to be 0.
    NULL is a macro that must be implemented as a null pointer constant. That means a constant expression equivalent to 0 or a constant expression equivalent to 0 cast to void*. Summarized, that means that NULL will generally be one of the following because anything else just adds clutter.
    Code:
    #define NULL 0
    Code:
    #define NULL ((void*)0)
    The standard is very specific about this, but you have to look in three or so different sections to get the whole story.

  15. #15
    Registered User
    Join Date
    Jul 2004
    Posts
    4

    Uhm yea...

    Not to sound like a total moron but I've got to imagine there is much simpler way to read an unknown number of variables if the type of variable is known. That whole code is needed just to read and unkown set of variables? Plus I must admit I find the code you wrote a bit confusing, I know this can be done without pointers so I was wondering if anyone knew another way?

    Thanks again for all the help,
    Spiros

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  2. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  3. Number Guessing
    By blacknapalm in forum C Programming
    Replies: 2
    Last Post: 10-01-2008, 01:48 AM
  4. reading a text file printing line number
    By bazzano in forum C Programming
    Replies: 4
    Last Post: 09-16-2005, 10:31 AM
  5. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-25-2001, 11:45 PM