How to input strings of any lengths into arrays of type: char *array[SIZE] ?

Discussion in 'C Programming' started by arkobose@gmail.com, May 15, 2005.

  1. Guest

    hey everyone!
    i have this little problem. consider the following declaration:

    char *array[4] = {"wilson", "string of any size", "etc", "input"};

    this is a common data structure used to store strings of any lengths
    into an array of pointers to char type variable.

    my problem is: given the declaration

    char *array[SIZE];
    how to store strings of any length into this array from the user input
    using functions like "scanf", "gets" etc. ?

    let me know if you get it!

    -thanks,
    arko
    , May 15, 2005
    #1
    1. Advertising

  2. Michael Mair Guest

    Re: How to input strings of any lengths into arrays of type: char*array[SIZE] ?

    wrote:
    > hey everyone!
    > i have this little problem. consider the following declaration:
    >
    > char *array[4] = {"wilson", "string of any size", "etc", "input"};
    >
    > this is a common data structure used to store strings of any lengths
    > into an array of pointers to char type variable.


    Nope. You do not store strings but pointers to the respective first
    character of these strings.
    Consider the difference between.
    char *cannot_be_modified = "foo";
    and
    char just_an_array[] = "foo";


    > my problem is: given the declaration
    >
    > char *array[SIZE];
    > how to store strings of any length into this array from the user input
    > using functions like "scanf", "gets" etc. ?


    Make array point to the buffer in which you want to store/have
    stored the "i"th string.


    > let me know if you get it!


    This I hereby do.

    Give us your best shot at it in the form of a compilable program
    and you will get more feedback.
    Otherwise, there is always the ring of homework with certain
    questions...


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, May 15, 2005
    #2
    1. Advertising

  3. In article <>,
    <> wrote:
    >my problem is: given the declaration


    > char *array[SIZE];
    >how to store strings of any length into this array from the user input
    >using functions like "scanf", "gets" etc. ?


    You don't. Functions "like" scanf() and gets() are functions
    that may return strings of indefinite length into the user buffer
    which is *assumed* to be "big enough". Clearly any assumption of
    "big enough" is going to be violated in the face of your
    requirement to be able to store strings of "any length" -- if
    the user provided a 7.2 exabyte long buffer, the program would
    fail the first time the input was 7.3 exabytes long.

    If you use fgets() instead of "functions like" scanf and gets,
    then you have the ability to specify a maximum input size that
    will not be exceeded. That gives you a chance to read a block
    of input at a time into a fixed-length buffer, then allocate
    dynamic memory to hold the contents. You could either create a
    linked-list of these dynamic buffers and then at the end create
    a single dynamic buffer long enough to hold the end result,
    or you could use realloc() as you went along -- simpler logic
    but much less efficient.

    Naturally, if your system only -has- 512 Mb of available memory,
    then you aren't going to be able to deal with the 7.3 exabyte long
    input, but at least you will be able to handle the situation
    smoothly whereas if you use functions "like" scanf and gets
    you would almost certainly crash in the attempt.

    Handling input of "any length" is a mugs game -- no matter how
    sophisticated your buffering, you are never going to be able to
    read "all" of /dev/zero or /dev/random (on Unix systems).
    --
    Entropy is the logarithm of probability -- Boltzmann
    Walter Roberson, May 15, 2005
    #3
  4. Michael Mair Guest

    Re: How to input strings of any lengths into arrays of type: char*array[SIZE] ?

    Walter Roberson wrote:
    > In article <>,
    > <> wrote:
    >
    >>my problem is: given the declaration

    >
    >> char *array[SIZE];
    >>how to store strings of any length into this array from the user input
    >>using functions like "scanf", "gets" etc. ?

    >
    > You don't. Functions "like" scanf() and gets() are functions
    > that may return strings of indefinite length into the user buffer
    > which is *assumed* to be "big enough". Clearly any assumption of
    > "big enough" is going to be violated in the face of your
    > requirement to be able to store strings of "any length" -- if
    > the user provided a 7.2 exabyte long buffer, the program would
    > fail the first time the input was 7.3 exabytes long.
    >
    > If you use fgets() instead of "functions like" scanf and gets,
    > then you have the ability to specify a maximum input size that
    > will not be exceeded.


    When using scanf(), one certainly can restrict the number of
    characters read.

    > That gives you a chance to read a block
    > of input at a time into a fixed-length buffer, then allocate
    > dynamic memory to hold the contents. You could either create a
    > linked-list of these dynamic buffers and then at the end create
    > a single dynamic buffer long enough to hold the end result,
    > or you could use realloc() as you went along -- simpler logic
    > but much less efficient.


    This point certainly can be debated. Increasing the buffer size
    by a factor instead of a fixed amount (maybe with a final
    realloc()ation in order to reduce the amount needed to the
    minimum may be more efficient).

    > Naturally, if your system only -has- 512 Mb of available memory,
    > then you aren't going to be able to deal with the 7.3 exabyte long
    > input, but at least you will be able to handle the situation
    > smoothly whereas if you use functions "like" scanf and gets
    > you would almost certainly crash in the attempt.
    >
    > Handling input of "any length" is a mugs game -- no matter how
    > sophisticated your buffering, you are never going to be able to
    > read "all" of /dev/zero or /dev/random (on Unix systems).


    Unless the system dies at a convenient moment... ;-)


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, May 15, 2005
    #4
  5. CBFalconer Guest

    Re: How to input strings of any lengths into arrays of type: char*array[SIZE] ?

    wrote:
    >

    .... snip ...
    >
    > my problem is: given the declaration
    >
    > char *array[SIZE];
    > how to store strings of any length into this array from the user
    > input using functions like "scanf", "gets" etc. ?


    You can't. Obviously, once you define a SIZE that is a limit.
    However there is a solution: store pointers to strings of varying
    size. You can form those strings in malloced memory, which can be
    adjusted to the actual string size. How do I do that, you ask?
    Simple - just download ggets.zip from my site, and compile and use
    it.

    <http://cbfalconer.home.att.net/download/ggets.zip>

    --
    Some informative links:
    news:news.announce.newusers
    http://www.geocities.com/nnqweb/
    http://www.catb.org/~esr/faqs/smart-questions.html
    http://www.caliburn.nl/topposting.html
    http://www.netmeister.org/news/learn2quote.html
    CBFalconer, May 15, 2005
    #5
  6. Guest

    Walter Roberson wrote:
    > In article <>,
    > <> wrote:
    > >my problem is: given the declaration

    >
    > > char *array[SIZE];
    > >how to store strings of any length into this array from the user

    input
    > >using functions like "scanf", "gets" etc. ?

    >
    > You don't. Functions "like" scanf() and gets() are functions
    > that may return strings of indefinite length into the user buffer
    > which is *assumed* to be "big enough". Clearly any assumption of
    > "big enough" is going to be violated in the face of your
    > requirement to be able to store strings of "any length" -- if
    > the user provided a 7.2 exabyte long buffer, the program would
    > fail the first time the input was 7.3 exabytes long.
    >
    > If you use fgets() instead of "functions like" scanf and gets,
    > then you have the ability to specify a maximum input size that
    > will not be exceeded. That gives you a chance to read a block
    > of input at a time into a fixed-length buffer, then allocate
    > dynamic memory to hold the contents. You could either create a
    > linked-list of these dynamic buffers and then at the end create
    > a single dynamic buffer long enough to hold the end result,
    > or you could use realloc() as you went along -- simpler logic
    > but much less efficient.
    >
    > Naturally, if your system only -has- 512 Mb of available memory,
    > then you aren't going to be able to deal with the 7.3 exabyte long
    > input, but at least you will be able to handle the situation
    > smoothly whereas if you use functions "like" scanf and gets
    > you would almost certainly crash in the attempt.
    >
    > Handling input of "any length" is a mugs game -- no matter how
    > sophisticated your buffering, you are never going to be able to
    > read "all" of /dev/zero or /dev/random (on Unix systems).
    > --
    > Entropy is the logarithm of probability -- Boltzmann


    dear Walter,
    consider the following program:

    #include<stdio.h>
    #define SIZE 1
    int main()
    {
    char *array[SIZE];
    scanf("%s", array[0]); // type a string of any length whatsoever.
    for(int i = 0; *(array[0] + i) != '\0'; i++)
    printf("%c", *(array[0] + i));

    return 0;
    }
    when you run this program, you will find that the "printf" outputs the
    whole string which you entered through "scanf", no matter how long your
    string was.
    now suppose you change the constant SIZE to some bigger value, 4, for
    example, and then modify the program to this:

    #include<stdio.h>
    #define SIZE 4

    int main()
    {
    char *array[SIZE] = {"string of any size", "type",
    "praetertranssubstantiationalistically", "another string"};

    for(int i = 0; i < SIZE; i++){
    for(int j = 0; *(array + j) != '\0'; j++){
    printf("%c", *(array + j));
    }
    printf("\n");
    }
    return 0;
    }

    then this program will output the strings with which the array has been
    initialized exactly.
    but if you want that the strings be entered at run time by user, rather
    than be given at initialization as above, then how do you do this?
    that is, during execution you type your strings one by one and they get
    stored exactly as in the above program.

    any ideas?

    -arko
    , May 15, 2005
    #6
  7. Artie Gold Guest

    Re: How to input strings of any lengths into arrays of type: char*array[SIZE] ?

    wrote:
    > Walter Roberson wrote:
    >
    >>In article <>,
    >> <> wrote:
    >>
    >>>my problem is: given the declaration

    >>
    >>> char *array[SIZE];
    >>>how to store strings of any length into this array from the user

    >
    > input
    >
    >>>using functions like "scanf", "gets" etc. ?

    >>
    >>You don't. Functions "like" scanf() and gets() are functions
    >>that may return strings of indefinite length into the user buffer
    >>which is *assumed* to be "big enough". Clearly any assumption of
    >>"big enough" is going to be violated in the face of your
    >>requirement to be able to store strings of "any length" -- if
    >>the user provided a 7.2 exabyte long buffer, the program would
    >>fail the first time the input was 7.3 exabytes long.
    >>
    >>If you use fgets() instead of "functions like" scanf and gets,
    >>then you have the ability to specify a maximum input size that
    >>will not be exceeded. That gives you a chance to read a block
    >>of input at a time into a fixed-length buffer, then allocate
    >>dynamic memory to hold the contents. You could either create a
    >>linked-list of these dynamic buffers and then at the end create
    >>a single dynamic buffer long enough to hold the end result,
    >>or you could use realloc() as you went along -- simpler logic
    >>but much less efficient.
    >>
    >>Naturally, if your system only -has- 512 Mb of available memory,
    >>then you aren't going to be able to deal with the 7.3 exabyte long
    >>input, but at least you will be able to handle the situation
    >>smoothly whereas if you use functions "like" scanf and gets
    >>you would almost certainly crash in the attempt.
    >>
    >>Handling input of "any length" is a mugs game -- no matter how
    >>sophisticated your buffering, you are never going to be able to
    >>read "all" of /dev/zero or /dev/random (on Unix systems).
    >>--
    >> Entropy is the logarithm of probability -- Boltzmann

    >
    >
    > dear Walter,
    > consider the following program:
    >
    > #include<stdio.h>
    > #define SIZE 1
    > int main()
    > {
    > char *array[SIZE];
    > scanf("%s", array[0]); // type a string of any length whatsoever.


    Undefined behavior -- array[0] is an uninitialized pointer. In this case
    it just *happened* to *seem* to work. Basically, you got unlucky.
    > for(int i = 0; *(array[0] + i) != '\0'; i++)


    > printf("%c", *(array[0] + i));
    >
    > return 0;
    > }
    > when you run this program, you will find that the "printf" outputs the
    > whole string which you entered through "scanf", no matter how long your
    > string was.


    Dumb luck (or lack of same).

    > now suppose you change the constant SIZE to some bigger value, 4, for
    > example, and then modify the program to this:
    >
    > #include<stdio.h>
    > #define SIZE 4
    >
    > int main()
    > {
    > char *array[SIZE] = {"string of any size", "type",
    > "praetertranssubstantiationalistically", "another string"};
    >
    > for(int i = 0; i < SIZE; i++){
    > for(int j = 0; *(array + j) != '\0'; j++){
    > printf("%c", *(array + j));
    > }
    > printf("\n");
    > }
    > return 0;
    > }
    >
    > then this program will output the strings with which the array has been
    > initialized exactly.
    > but if you want that the strings be entered at run time by user, rather
    > than be given at initialization as above, then how do you do this?
    > that is, during execution you type your strings one by one and they get
    > stored exactly as in the above program.
    >
    > any ideas?
    >


    Sure. See the following for a thorough discussion of the subject:

    http://users.powernet.co.uk/eton/c/fgetdata.html

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
    Artie Gold, May 15, 2005
    #7
  8. Malcolm Guest

    <> wrote
    > char *array[SIZE];
    > how to store strings of any length into this array from the user input
    > using functions like "scanf", "gets" etc. ?
    >

    char *array[SIZE];
    char buff[1024];

    for(i=0;i<SIZE;i++)
    {
    fgets(buff, 1024, stdin);
    ptr = strchr(buff, '\n');
    /* this is absolutely vital. fgets() is no improvement whatsoever over
    gets() unless
    you handle buffer overflow correctly. Wrong results are often worse than a
    crash which is the most likely result of gets() being fed an over-long
    line. */
    if(ptr == 0)
    {
    printf("Your line was over 1024 characters long. I will have to look
    up realloc"
    "and do a bit more work to solve this problem. For now let's quit\n");
    exit(EXIT_FAILURE);
    }
    *ptr = 0;
    array = mystrdup(buff);
    if(!array)
    {
    printf("Out of memory\n");
    exit(EXIT_FAILURE);
    }
    }

    char *mystrdup(const char *str)
    {
    char *answer = malloc(strlen(str) + 1);
    if(answer)
    strcpy(answer, str);
    return answer;
    }
    Malcolm, May 15, 2005
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Pfaff
    Replies:
    5
    Views:
    473
    Tristan Miller
    Jan 17, 2004
  2. Replies:
    12
    Views:
    695
    Michael Wojcik
    May 19, 2005
  3. jt
    Replies:
    3
    Views:
    925
    Keith Thompson
    May 23, 2005
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,043
    Ian Collins
    May 9, 2006
  5. Replies:
    5
    Views:
    451
Loading...

Share This Page