2

So I have this piece of code:

void main()
{
    char word[21]={0}; // changed from 20 to 21 because of '\0'.
    // do {
    scanf("%s", &word);
    // } while (strlen(niz)>20);  this line is useless because program crashes anyway
}
  1. Question: The thing is I want to limit the number of characters user wants to input to 20. Sure I could reserve more memory for word[] but if I went over certain number the program would crash again. How do you get around this in C?

  2. Question: Is there any way I can allocate needed memory for the string just after user enters it. For example if user enters string that has length of 999 can I allocate sizeof(string) * strlen(word) + 1 bytes of memory?

Note: if strlen() exceeds certain limit I want to prompt user to enter a new string again.

Firmus
  • 195
  • 1
  • 1
  • 8
  • for 2) - not really. you have to allocate a buffer ahead-of-time. there won't be a magical area for the system to keep the input data until you can figure out how big it is. Once you call scanf, control is transferred to the input system until the user enters an eof/eol character. – Marc B Dec 22 '14 at 21:11
  • 1
    the scanf format conversion parameters '%s' can have length and other details, depending on the conversion type, so you could say: scanf("%20s", &word); – user3629249 Dec 23 '14 at 00:39

5 Answers5

2

You can limit the string length by using fgets:

fgets(word, sizeof(word), stdin);  

For second part:
Unfortunately, In C you can't allocate the exact amount of memory needed for the string entered. The reason is that you need to know the length of string before allocating memory for it and for this you must have to store that string in a buffer.

If you want to enter a string of any size and save memory at the same time, then use realloc.
Test program:

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

int main(void)
{
    char *s = malloc(1);
    printf("Enter a string: \t"); // It can be of any length
    int c;
    int i = 0;
    do
    {
        c = getchar();
        s[i++] = c;
        s = realloc(s, i+1);
    }while(c != '\n' && c != EOF);

    s[i] = '\0';
    printf("Entered string: \t%s", s);
    return 0;
}
haccks
  • 104,019
  • 25
  • 176
  • 264
1

Some versions of scanf support m modifier. For example in glibc>=2.7. They allocate necessary buffer for the user:

   char *p;
   int n = scanf("%ms", &p);
   if (n == 1) {
       printf("read: %s\n", p);
       free(p);
   } else {
       // error
   }

There is also older a modifier which does the same.

Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
0

Put a character constant in front of s in %s:

scanf("%20s", &word);

Your second question: in short No. You need memory space to take the input. A common solution however, to reduce allocations is do do something like:

char tmp[1000];
char *strptr;

scanf("%s", &temp);
strptr = malloc(sizeof(char)*(strlen(tmp)+1));

but that will only save you space if you call this function 1000s of times.

Carlise
  • 124
  • 8
  • Thanks! My program doesn't crash now and I can prompt user if he enters more than 20 chars. I also found this solution: http://stackoverflow.com/questions/8164000/how-to-dynamically-allocate-memory-space-for-a-string-and-get-that-string-from-u?rq=1 – Firmus Dec 22 '14 at 21:24
  • That answer is a good solution. It's how I generally take user input without wasting allocated space. – Carlise Dec 22 '14 at 21:55
0

You can limit the input by using fgets instead.

fgets(word, sizeof(word), stdin);

if later need to extract things from the string use sscanf

AndersK
  • 35,813
  • 6
  • 60
  • 86
0

Use command line arguments.. main(int argc, char *argv[ ])

Here argc will tell you how many arguments are passed when you are giving executable.

argv will give you the data or string.. Just give it to a 'char *'.

K K SAI
  • 1
  • 1