Reading in variable-length string user input in C

I am trying to read in user input of variable length and perform some operation (for example, finding a substring inside a string).

The problem is that I do not know how large my lines are (it is quite possible that the text can be 3000-4000 characters).

I am adding sample code that I tried and the output:

char t[],p[]; int main(int argc, char** argv) { fflush(stdin); printf(" enter a string\n"); scanf("%s",t); printf(" enter a pattern\n"); scanf("%s",p); int m=strlen(t); int n =strlen(p); printf(" text is %s %d pattrn is %s %d \n",t,m,p,n); return (EXIT_SUCCESS); } 

and output:

 enter a string bhavya enter a pattern av text is bav 3 pattrn is av 2 
+6
source share
4 answers

Please, never use insecure things like scanf("%s") or my personal ones not favorite, gets() - there is no way to prevent buffer overflows for such things.

You can use a more secure input method, for example:

 #include <stdio.h> #include <string.h> #define OK 0 #define NO_INPUT 1 #define TOO_LONG 2 static int getLine (char *prmpt, char *buff, size_t sz) { int ch, extra; // Get line with buffer overrun protection. if (prmpt != NULL) { printf ("%s", prmpt); fflush (stdout); } if (fgets (buff, sz, stdin) == NULL) return NO_INPUT; // If it was too long, there'll be no newline. In that case, we flush // to end of line so that excess doesn't affect the next call. if (buff[strlen(buff)-1] != '\n') { extra = 0; while (((ch = getchar()) != '\n') && (ch != EOF)) extra = 1; return (extra == 1) ? TOO_LONG : OK; } // Otherwise remove newline and give string back to caller. buff[strlen(buff)-1] = '\0'; return OK; } 

Then you can set the maximum size, and it will detect that too much data has been entered in the line, as well as the rest of the line, so it does not affect the next input operation.

You can check it with something like:

 // Test program for getLine(). int main (void) { int rc; char buff[10]; rc = getLine ("Enter string> ", buff, sizeof(buff)); if (rc == NO_INPUT) { // Extra NL since my system doesn't output that on EOF. printf ("\nNo input\n"); return 1; } if (rc == TOO_LONG) { printf ("Input too long [%s]\n", buff); return 1; } printf ("OK [%s]\n", buff); return 0; } 
+10
source

In practice, you do not have to worry too much to be precise. Give yourself some time to have memory on the stack and work on it. Once you want to pass the data further, you can use strdup(buffer) and have it on the heap. Know your limits. :-)

 int main(int argc, char** argv) { char text[4096]; char pattern[4096]; fflush(stdin); printf(" enter a string\n"); fgets(text, sizeof(text), stdin); printf(" enter a pattern\n"); fgets(pattern, sizeof(pattern), stdin); int m=strlen(text); int n =strlen(pattern); printf(" text is %s %d pattrn is %s %d \n",text,m,pattern,n); return (EXIT_SUCCESS); } 
+1
source

Do not use scanf or gets for this, because, as you say, there is no real way to find out how long the input will take. Rather, use fgets , using stdin as the last parameter. fgets allows you to specify the maximum number of characters to be read. You can always come back and read more if you need.

scanf(%s) and gets read until they find the trailing character and can significantly exceed the length of your buffer, which can make fixing problems difficult.

0
source

The main problem in your case is the presence of char arrays of unknown size. Just specify the size of the array in the ad.

 int main(int argc, char** argv) { int s1[4096], s2[4096]; fflush(stdin); printf(" enter a string\n"); scanf("%s", s1); printf(" enter a pattern\n"); scanf("%s", s2); int m = strlen(s1); int n = strlen(s2); printf(" text is %s of length %d, pattern is %s of length %d \n", s1, m, s2, n); return (EXIT_SUCCESS); } 
0
source

Source: https://habr.com/ru/post/898743/


All Articles