0

I want to take an input in c and don't know the array size. please suggest me the ways how to do this..

hello this is
a sample
string to test.
Phantom
  • 1,704
  • 4
  • 17
  • 32
martin
  • 49
  • 2
  • 10

3 Answers3

0

malloc is one way:

char* const string = (char*)malloc(   NCharacters   ); // allocate it
...use string...
free(string); // free it

where NCharacters is the number of characters you need in that array.

justin
  • 104,054
  • 14
  • 179
  • 226
0

If you're writing the code yourself, the answer will involve malloc() and realloc(), and maybe strdup(). You're going to need to read the strings (lines) into a large character array, then copy the strings (with strdup()) into a dynamically sized array of character pointers.

char line[4096];
char **strings = 0;
size_t num_strings = 0;
size_t max_strings = 0;

while (fgets(line, sizeof(line), stdin) != 0)
{
    if (num_strings >= max_strings)
    {
        size_t new_number = 2 * (max_strings + 1);
        char **new_strings = realloc(strings, new_number * sizeof(char *));
        if (new_strings == 0)
            ...memory allocation failed...handle error...
        strings = new_strings;
        max_strings = new_number;
    }
    strings[num_strings++] = strdup(line);
}

After this loop, there's enough space for max_strings, but only num_strings are in use. You could check that strdup() succeeded and handle a memory allocation error there too, or you can wait until you try accessing the values in the array to spot that trouble. This code exploits the fact that realloc() allocates memory afresh when the 'old' pointer is null. If you prefer to use malloc() for the initial allocation, you might use:

size_t num_strings = 0;
size_t max_strings = 2;
char **strings = malloc(max_strings * sizeof(char *));

if (strings == 0)
    ...handle out of memory condition...

If you don't have strdup() automatically, it is easy enough to write your own:

char *strdup(const char *str)
{
    size_t length = strlen(str) + 1;
    char  *target = malloc(length);
    if (target != 0)
        memmove(target, str, length);
    return target;
}

If you are working on a system with support for POSIX getline(), you can simply use that:

char   *buffer = 0;
size_t  buflen = 0;
ssize_t length;
while ((length = getline(&buffer, &buflen, stdin)) != -1)  // Not EOF!
{
    …use string in buffer, which still has the newline…
}
free(buffer);  // Avoid leaks
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • memmove() ? Probably it will work, but I think you meant memcpy(). – wildplasser May 17 '13 at 07:23
  • @wildplasser: No, I meant `memmove()`. In this context, `memcpy()` would also work, but `memcpy()` does not always work and `memmove()` does always work, so I always use `memmove()` because it is utterly reliable, unlike `memcpy()`. – Jonathan Leffler May 17 '13 at 07:26
  • 1
    It may not harm, but it may confuse newbees. NTW: I don't like comaring `target` too a numerical constant zero, either. I would prefer: `if (target) memcpy(target, str, length);` – wildplasser May 17 '13 at 07:32
  • Each to their own; I don't like `if (target)`... – Jonathan Leffler May 17 '13 at 07:42
-1

Thank you for the above answers. I have found out the exact answer that I wanted. I hope it will help other people's questions also.

while ((ch == getchar()) != '$')
{
    scanf("%c", &ch);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
martin
  • 49
  • 2
  • 10
  • There are so many problems with this fragment it is scary. You compare the result of `getchar()` with `ch`, instead of assigning. The result of the comparison will be 0 or 1, neither of which is the same as `'$'` in any standard code set, so the loop continues forever. If `ch` is of type `char`, the `scanf()` reads another character (no checking); if `ch` is of type `int` (as it should be for receiving the result of `getchar()`), then the call to `scanf()` is passing the wrong pointer type (though you might not spot the problem on little-endian machines). All of which adds up to trouble. – Jonathan Leffler Feb 23 '16 at 14:57