Reputation: 321
I know this is possible
char text[A_BIG_NUMBER];
printf("Enter your name");
scanf("%s",text);
but is there a way to do this? (without using a char array as backup)
char* text;
printf("Enter your name");
scanf("%s",text);
while first way is easy but if A_BIG_NUMBER is not big enough to hold the string entered by user then it will create problems for the rest of the code, on the other hand if we use a large number then it wastes memory!
Thanks
Edit: Sorry for the wrong tag. I am asking about C only.
Upvotes: 0
Views: 765
Reputation: 3451
You can use getchar, here is a sample code:
int size = 128;
char *s = (char*)malloc (size);
char c;
int i;
while ((c = getchar ()) != '\n' && c != EOF)
{
s[i] = c;
++i;
if (i == size)
{
size = size * 2;
char *tmp = realloc (s, size);
if (tmp != NULL)
s = tmp;
else ; // error, try with malloc and copy or exit or whatever you want
}
}
s[i] = 0;
Upvotes: 0
Reputation: 477060
Since you say C++, the answer is "yes, string":
std::string name;
std::cout << "Enter your name: ";
if (!std::getline(std::cin, name)) { /* unexpected end of input */ }
// now use "name"
As you discovered, you generally need dynamic allocation to store external data. (Your code is not very general: you can't have very large automatic arrays, and the fixed size adds arbitrary magic numbers and constraints.) C++ is the perfect language for encapsulating the details of dynamic allocation and cleanup, so that you can use simple, automatic variables to do all the work for you.
If you don't like iostreams, you can rig up your own overload bool getline(std::FILE *, std::string &)
that loops over calls to std::fgets
and +=
to extract a complete line.
Upvotes: 3
Reputation: 108938
Use a small(ish) buffer with fgets()
in a loop. Inside the loop realloc() the final destination.
/* UNTESTED */
char smallish[1000];
char *destin = NULL;
size_t destin_size = 1;
while (fgets(smallish, sizeof smallish, stdin)) {
destin_size += strlen(smallish);
char *tmp = realloc(destin, destin_size);
if (!tmp) /* deal with error */;
destin = tmp;
strcat(destin, smallish);
if (smallish[strlen(smallish) - 1] == '\n') break;
}
/* use destin */
free(destin);
Upvotes: 0
Reputation: 1238
char* does not allocate memory for storing the user input string and that is the reason the second code does not work.
If you are worried about the memory usage / wastage, you can overcome these limitations using program specific stack/heap.
Upvotes: 1
Reputation: 726599
You can certainly use dynamically allocated memory instead of the array, but the fundamental issue of the overrun remains there:
char *text = malloc(A_BIG_NUMBER*sizeof(char));
printf("Enter your name");
scanf("%s",text);
You need to tell scanf
that the space is limited, like this:
char text[201];
printf("Enter your name");
scanf("%200s",text);
Note that text[201]
has an extra character space for the terminator: %200s
limits the input to 200 "real" characters, so you need to provide an extra char
for the '\0'
.
Upvotes: 1