# Thread: Number user input

1. Originally Posted by jimtuv
from Wikipidia: functional decomposition .... I love Google search!
Yeah, I just read that one too.

To take all of what is put in stding woudn't that take a variable length array?? Or I could just save the good and just chuck the leftover would be the my first thought.
You mean input a string of any length safely? I posted this here earlier in the week, it's the "general idea" behind my preferred method of input:

Code:
```#define BSZ 1024
char *getline(FILE *st) {
char buf[BSZ],
*r;
int len, total = 0;

fgets(buf,BSZ,st);
len = strlen(buf);
r = malloc(len+1);      // may want to error check this
strcpy(r,buf);

/* deal with absurdly long lines */
while ((len == BSZ-1)) {
total += len;
if (!fgets(buf,BSZ,st)) break;
len = strlen(buf);
r = realloc(r,total+len+1);
strcat(r,buf);
}

return r;
}```
So you could use this:
Code:
```char *input = getline(stdin);
[.....]
free(input);```
BSZ can be anything (it could be 2, or 16, or whatever) it will still work the same, only larger numbers are more efficient. There is no point using less than 1K even if the input is usually short, IMO. Also, if your target OS can return NULL on malloc/realloc you will want to do "out of memory" error checking.

You can adapt the function to say, sscanf different parts of the line and return a struct instead.

2. Originally Posted by MK27
BSZ can be anything (it could be 2, or 16, or whatever) it will still work the same, only larger numbers are more efficient. There is no point using less than 1K even if the input is usually short, IMO.
Yes, in fact, if BSZ is too small, you are going to suffer terribly: the dynamic array will need to be frequently expanded, and each time it is expanded, strcat is going to take its time to find the end of the current string, and only then append to it.

You can fix this by keeping track of both total size and capacity and expanding the capacity by a factor (e.g., 1.5) instead of a fixed amount, but then you may end up wasting space (unless you trim the capacity to the size when you are done), plus with a sufficiently large BSZ the problem becomes more about theoretical time complexity than an actual problem.

3. see this is where my noobness get in the way.

I just finished learning about pointers and arrays. Unfortunately haven't hit memory allocation yet. So I don't recognize malloc or realloc yet. Or I should say I don't yet know the proper way to use them yet.

4. Perhaps you should revisit the problem once you've learned dynamic memory, then.

5. I think that would be a good Idea. I am picking up pretty quick but don't want to get to far over my head.

first I am going to learn about searching, sorting and multi dimensional arrays, then I think structures and strings. After that I will get back into IO and maybe be then I will be ready to learn more advanced topics like memory allocation.

6. Originally Posted by jimtuv
first I am going to learn about searching, sorting [...] more advanced topics like memory allocation.
Memory allocation is not a more advanced topic than searching and sorting. It's fairly basic, or at least, in C the fundamentals of it are quite basic. You just need to understand the use of a few simple commands -- malloc() and free().

7. Now, if only you hadn't picked C as the language to learn...
Heh. Good luck.

8. Let me see how far I can get with the above example.

Code:
`char *getline(FILE *st)`
This would be a function that returns a pointer of char type and takes a pointer File type as an argument. is this right so far?

Code:
```        char buf[BSZ],
*r;
int len, total = 0;```
This part sets up a array of 1024 elements type char and a char pointer as of yet pointing nowhere. Then an int len (later used for length of the string) and total setting it to 0;

9. Originally Posted by jimtuv
This would be a function that returns a pointer of char type and takes a pointer File type as an argument. is this right so far?
Yes.

Originally Posted by jimtuv
This would be a function that returns a pointer of char type and takes a pointer File type as an argument. is this right so far?
Yes. Incidentally, strlen() returns a size_t, not an int, but for these purposes there is no problem, other than a possible rather benign compiler warning.

10. Code:
```fgets(buf,BSZ,st);
len = strlen(buf);
r = malloc(len+1);      // may want to error check this
strcpy(r,buf);```
the fgets gets the line size 1024 from the file pointed to by st

the next line points r to a newly allocated area of memory that is the size 1024+1 if fgets a complete line otherwise it would be whatever the string length was + 1 for the '\n' at the end of string

strcpy then copies that string from the newly allocated memory space pointed to by r and copies it into buf.

11. Originally Posted by jimtuv
the next line points r to a newly allocated area of memory that is the size 1024+1 if fgets a complete line otherwise it would be whatever the string length was + 1 for the '\n' at the end of string
No, the +1 is for the null character, which is not included in the count returned by strlen(). fgets() would read in the '\n' if it were among the first 1023 characters.

Originally Posted by jimtuv
strcpy then copies that string from the newly allocated memory space pointed to by r and copies it into buf.
You got it the other way round

12. opps just typed that backwards I did mean that it was copiying from buf to r. It only makes sense because the string is in buf after the fgets.

13. Code:
```while ((len == BSZ-1)) {
total += len;
if (!fgets(buf,BSZ,st)) break;
len = strlen(buf);
r = realloc(r,total+len+1);
strcat(r,buf);
}```
Ok let see. Its a while loop with the condition that the len (string length) is equal 1023 so if it is true then it sets total to total + len that would give total a initial value of up to 1023 on the first loop.

Next it gets another chunk of 1024 size data from st, and if the return from fgets is not null then it breaks out of the loop and returns the pointer r.

if not it changes the len to the new string length in buf
points r to a now larger chunck of memory resized by the realloc function by adding the total length of the first string to the new string length and 1 extra for the null

now copy using strcat from the buff to the memory pointed to by r

so my guess is malloc allocates memory and realloc changes it size by either increasing or decreasing the allocated memory block if either fails they will return a null pointer.

malloc needs a size and realloc needs a pointer and a size. I would assume a negative size would reduce the allocated memory size.

Then you have to make sure to use free(*pointer to memory block) at some point to release the memory. If you don't you would have a memory leak right??

14. Originally Posted by jimtuv
malloc needs a size and realloc needs a pointer and a size. I would assume a negative size would reduce the allocated memory size.
Are you guessing what these standard functions do???
You should read the documentation. not playing guessing game!!!

15. Originally Posted by Bayint Naung
Are you guessing what these standard functions do???
You should read the documentation. not playing guessing game!!!
Just a poor choice of words. I never guess at anything. However my understanding maybe incorrect. Here is where I have been looking to find out how the functions work.

C and C++ Library Function Listing

The C Library Reference Guide

C Library - C++ Reference

I should have said "from what I read I think" instead of guess. :P

Popular pages Recent additions