0

In my application, we take in char values one at a time and we need to be able to but them into a string. We are assembling these strings one by one by putting the char values into a char array, then clearing the array. However the strings are each different lengths and we are unable to determine the size of the string. How can we change the sizes of the array to add more space as we need it?

Also, how can we print out the array?

  • Wonder if pointers would be a good alternative to using arrays in this scenario. – dreamerkumar Dec 01 '13 at 16:19
  • @VishalKumar Pointers are only useful if they point to somewhere. Your statement per se is quite senseless without this thought. – glglgl Dec 01 '13 at 18:38
  • Sorry for the misleading comment. I really meant using pointers to create a linked list. That gives you all the flexibility in assigning memory to each element in the linked list. – dreamerkumar Dec 03 '13 at 06:58

2 Answers2

4

If the array was dynamically allocated with malloc, you can resize it with realloc:

int array_size = 1024;
char *array = (char *) malloc(array_size);

int n = 0;
char c;
while ((c = getchar()) != EOF) {
    array[n++] = c;
    if (n >= array_size) {
        array_size += 1024;
        array = (char *) realloc(array_size);
    }
}
array[n] = '\0';

For printing out the contents of the array, you can simply pass it to printf or puts:

printf("%s\n", array);
puts(array);
Tim Pierce
  • 5,514
  • 1
  • 15
  • 31
  • 2
    why [`sizeof(char)`](http://stackoverflow.com/q/2215445/296974)? And [why `(char *)` before `malloc()`](http://stackoverflow.com/q/605845/296974)? – glglgl Dec 01 '13 at 16:23
  • For consistency and to be explicit about your intentions, but also to account for building on a machine on which one char is not one machine byte. – Tim Pierce Dec 01 '13 at 16:26
  • 1
    Ouch. A char is *per definition* *always* one byte. See the link I posted. – glglgl Dec 01 '13 at 16:32
  • You have a good point about `sizeof(char)` being defined by the C standard to equal 1. My apologies for my old-school style. I'll update the answer. I maintain that explicitly casting to the desired type is a good habit, though I see that will not make me popular in SO. – Tim Pierce Dec 01 '13 at 16:33
  • 1
    @qwrrty: `sizeof (char)` is always 1 by definition, regardless of the native byte size. Secondly, casting the result of `malloc` and `realloc` is not only unnecessary, it can suppress a useful diagnostic (under C90, anyway). The whole point behind the `void *` type is that you don't *need* to perform any casting gymnastics to do an assignment. – John Bode Dec 01 '13 at 16:34
0

if you don'y know the size you are going to need and are adding one character at a time you can consider using a linked list. It can grow as much as you need it to. The disadvntages would be lookup is kind of slow, and if you need to free the memory, or clear it you would have to do this for each element, one at a time.

You can also take the dynamic array approach: allocate a certain size which you consider large enough and when that is 80% full, allocate a new buffer, twice as large and copy the contents of the old one in the new, larger one.

Pandrei
  • 4,843
  • 3
  • 27
  • 44
  • Why when it is 80% full? 100% seems a better choice to me. Your way, you always allocate 20% too much which is never used and needed. – glglgl Dec 01 '13 at 16:33
  • 80% is really just and example and it's a commonly used threshold. The reason you don'y wait until the buffer is full is that you want to avoid the situation when you have to allocate more memory just when you need it. it'll be very time consuming to allocate a new, larger buffer, and copy the contents of the old one when you run out of memory. But if you plan for this operation to happen when you are'n filling the buffer with data, the penalty is almost non-existant – Pandrei Dec 01 '13 at 16:41
  • Why copy? `realloc` allows you to allocate additional memory at the end of the block, if it turns out that block of memory is too small. – Elias Van Ootegem Dec 01 '13 at 16:42
  • 1
    actually realloc, sometimes copies the data to a new location if there is not enough space; so that's why I said copy - it's really up to you how you do the copy. But yes, realloc can do it for you. – Pandrei Dec 01 '13 at 16:47
  • @Pandrei: Of course `realloc` has to copy sometimes, but it'll only copy if required. You suggest to copy regardless... – Elias Van Ootegem Dec 01 '13 at 16:49
  • @EliasVanOotegem I only suggested the general solution, theoretical if you wish. I never said anything about implementation. If you want to focus more on the implementation, realloc is probably your best bet. – Pandrei Dec 01 '13 at 16:51
  • @Pandrei 80% is useful if you can extend the buffer at regular intervals to uncouple buffer usage and buffer maintenance. But you are right, if you want to cope with the situation that no more memory can be provided, it can be a useful way of going. – glglgl Dec 01 '13 at 18:36
  • @EliasVanOotegem You always have to cope with the worst case. – glglgl Dec 01 '13 at 18:37