A very simple scanf version can also be used:
#include <stdio.h>
#define MAXL 64
int main (void) {
char str[MAXL] = {0};
printf ("\n Enter a string ([enter] alone to quit)\n");
while (printf (" > ") && scanf ("%63[^\n]%*c", str) == 1)
{
/* do whatever in your code */
printf (" result: %s\n", str);
}
return 0;
}
Use/Output
$ ./bin/scanf_enter_quits
Enter a string ([enter] alone to quit)
> string
result: string
> another
result: another
>
Note: MAXL-1 added as maximum width specifier for scanf to prevent write beyond end of array.
getline Example
getline by dynamically allocating the line buffer allows you to accept a line as long as you want to give it. It can be billions of characters (up to the extent of your memory). This is a strength and a weakness. If you need to limit the amount of data you accept, it is up to you to check/validate/etc....
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *str = NULL;
size_t n = 0;
ssize_t nchr = 0;
printf ("\n Enter a string ([enter] alone to quit)\n");
while (printf (" > ") && (nchr = getline (&str, &n, stdin)) > 1)
{
str[--nchr] = 0; /* strip newline from input */
printf (" (str: %s)\n", str); /* do whatever in your code */
}
if (str) free (str);
return 0;
}
Use/Output
$ ./bin/getline_enter_quits
Enter a string ([enter] alone to quit)
> string one as long as you want
(str: string one as long as you want)
> string 2 make it 1000 chars.........................................
(str: string 2 make it 1000 chars.........................................)
>
scanf Dynamic Allocation
You can also have scanf dynamically allocate the space for you by using the m conversion specifier (older versions of scanf use the a conversion specifier for this purpose). You must also provide a pointer-to-pointer to accept the address in this case. (e.g. scanf ("%m[^\n]%*c", &str) ).
#include
#include
int main (void) {
char *str = NULL;
printf ("\n Enter a string ([enter] alone to quit)\n");
while (printf (" > ") && scanf ("%m[^\n]%*c", &str) == 1)
{
printf (" (str: %s)\n", str); /* do whatever in your code */
if (str) free (str); /* you must free each loop */
str = NULL;
}
if (str) free (str);
return 0;
}
Use/Output
$ ./bin/scanf_dyn_enter_quits
Enter a string ([enter] alone to quit)
> some string as long as you want
(str: some string as long as you want)
> another string any length .......... ............. .............
(str: another string any length .......... ............. .............)
>
whileloop would handle this case easily, while a recursive program could crash because the recursion would be too deep (leading to a stack overflow and a segmentation fault).