473,782 Members | 2,454 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Proper way to input a dynamically-allocated string

I know it must sound like a newbie question, but I never really had to
bother with that before, and I didn't even find an answer in the c.l.c
FAQ

I'd like to know what's the really proper way for input a string in an
array of char that's dynamically allocated. I mean, I wish not to see
any such things as char mystring[100]; I don't want to see any number
(if possible) I just want to declare something like char *mystring; and
then I don't know how allocate it with just as many chars (with the
space for the \0 of course) as you get from stdin.

I'd really like to know once for all what's the smartest way of
inputing strings from stdin and storing them in a way so they take just
the needed space and I don't want to see any number such as 100 or
10,000 or even 4,294,967,296 in my code. Any way it can be done?

Dec 9 '05
48 2254
On 2005-12-09, Michel Rouzic <Mi********@yah oo.fr> wrote:

Eric Sosman wrote:
Michel Rouzic wrote:
> Eric Sosman wrote:
>
>>Michel Rouzic wrote:
>>
>>
>>>I know it must sound like a newbie question, but I never really had to
>>>bother with that before, and I didn't even find an answer in the c.l.c
>>>FAQ
>>>
>>>I'd like to know what's the really proper way for input a string in an
>>>array of char that's dynamically allocated. I mean, I wish not to see
>>>any such things as char mystring[100]; I don't want to see any number
>>>(if possible) I just want to declare something like char *mystring; and
>>>then I don't know how allocate it with just as many chars (with the
>>>space for the \0 of course) as you get from stdin.
>>>
>>>I'd really like to know once for all what's the smartest way of
>>>inputing strings from stdin and storing them in a way so they take just
>>>the needed space and I don't want to see any number such as 100 or
>>>10,000 or even 4,294,967,296 in my code. Any way it can be done?
>>
>> Let's suppose you're reading complete '\n'-terminated lines,
>>the way fgets() does but with no explicit length limit. You
>>could do something like this (pseudocode, no error checking):
>>
>> buffer = <empty>
>> do {
>> expand buffer with realloc()
>> append next input character
>> } while (character wasn't '\n');
>> expand buffer with realloc()
>> append '\0'
>>
>> For efficiency's sake you'd probably want to avoid quite
>>so many trips in and out of the memory allocator, so a refinement
>>would be to start with a roomier buffer and expand by more than
>>one character at a time if necessary. (My own function for doing
>>this -- everybody writes one eventually -- begins with 100 characters
>>and adds half the buffer's current size each time it needs to expand:
>>100, 150, 225, ...)
>>
>> Once you've read the entire line you can, if you like, realloc()
>>the buffer one final time to trim it to the exact size. I find
>>that's seldom worth the bother: your program is probably going to
>>process the line and free() or re-use the buffer pretty soon.
>
>
> That's the method I like the best. I wouldn't bother with make larger
> buffers anyways, would make things too complicated, and things don't
> have to be sooo efficient when it comes to inputting strings, what
> matters the most is the result. i think I made your idea work pretty
> good, tell me if you think yous potted anything wrong with it, I GDBed
> it and the content of the memory looked fine
>
> int i;
> char *mystring;
>
> i=0;
> mystring=NULL;
> do
> {
> mystring=reallo c(mystring, i+1);
> mystring[i]=getchar();
> i++;
> }
> while (mystring[i-1]!='\n');
> mystring[i-1]='\0';
That's the general idea. As written, though, it's not
very robust: it's oblivious to realloc() failures and to
end-of-file or errors on the standard input. Pay attention
to the Sixth Commandment

"If a function be advertised to return an error code in the event of
difficulties, thou shalt check for that code, yea, even though the
checks triple the size of thy code..."


unless you _really_ don't care whether it succeeds or fails

what are you going to do if a printf fails? what if you just want to
continue?
realloc() failures? never heard of that (maybe cuz im quite new to all
that), what can happen with it?
it returns a null pointer because it didn't find enough memory
how can you get an EOF or some error from stdin?
someone types the EOF character, or interrupts [sending a signal on read
can possibly cause a read to fail in addition to calling a signal
handler]
you know, I care to know about why I should check for errors, and about
what can cause them and what I should do about it, but so far (and you
can understand that) I like to keep my code as simple as possible,
mostly that I consider that my program should work only as far as it is
used correctly (like, if a program is supposed to have a .wav file in
input, and the user put a .mp3 or anything else instead, I don't wanna
bother with doing stuff that will tell him "you need to input a .wav
file", i rather let him have a segmentation fault)


if you do something that can cause a segmentation fault, it could very
well cause worse.
Dec 9 '05 #11
Eric Sosman wrote:
For efficiency's sake you'd probably want to avoid quite
so many trips in and out of the memory allocator, so a refinement
would be to start with a roomier buffer and expand by more than
one character at a time if necessary. (My own function for doing
this -- everybody writes one eventually -- begins with 100 characters
and adds half the buffer's current size each time it needs to expand:
100, 150, 225, ...)


The way it was done in K&P Programming Practice,
where they started with a one char sized buffer
and doubled the size every time there was no space left.
I`s a good "golden middle" type idea, i think.
Dec 9 '05 #12
On 2005-12-10, grayhag <ue***@yahoo.co m> wrote:
Eric Sosman wrote:
For efficiency's sake you'd probably want to avoid quite so many
trips in and out of the memory allocator, so a refinement would be to
start with a roomier buffer and expand by more than one character at
a time if necessary. (My own function for doing this -- everybody
writes one eventually -- begins with 100 characters and adds half the
buffer's current size each time it needs to expand: 100, 150, 225,
...)


The way it was done in K&P Programming Practice, where they started
with a one char sized buffer and doubled the size every time there was
no space left. I`s a good "golden middle" type idea, i think.


doubling it each time actually reduces the worst-case complexity [of the
entire operation] from O(n^2) to O(n). I'm not sure what complexity you
end up with adding less than the full previous size. probably something
like nlogn or n^1.5
Dec 9 '05 #13
Michel Rouzic wrote:
Eric Sosman wrote:
Other observations: `int' should probably be `size_t'
as for the size_t thing, well i could cast it for realloc, like this :
mystring=reallo c(mystring, (size_t) i+1);


Why on earth would you think that? You *really* need to start working
through a decent text book.
other than that, I think i
should leave it to int, unless it is ok to do iterations and refer to
some element of an array by a size_t, which i doubt


Again, what on earth makes you think that? Of course you can use a
size_t variable for indexing in to an array.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 9 '05 #14
Michel Rouzic wrote:
Keith Thompson wrote:


<snip>
The speed of that code while reading input probably isn't going to be
much of an issue, but the multiple calls to realloc() might cause
excessive heap fragmentation, which could cause problems elsewhere in
your program. (The standard does use the term "heap", but you get the
idea.)


does it mean that the elements of my array won't be contigous?


No, it means the free space in your heap will be fragmented. Any memory
block returned by *alloc is always contiguous.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 9 '05 #15
Michel Rouzic wrote:

<snip>
"If a function be advertised to return an error code in the event of
difficulties, thou shalt check for that code, yea, even though the
checks triple the size of thy code..."

ok, I guess I should do that but.... well... as it says, it makes the
code much longer and makes it harder to read and, well, I wouldn't know
what to do with an error anyways, I mean, if the return code ain't
right, i might display something like "the return code ain't right\n"
and don't know what I should do.
If nothing else you can terminate the program with an error message
saying that it has failed.
realloc() failures? never heard of that (maybe cuz im quite new to all
that), what can happen with it?
There might not be a large enough block of free memory because you have
fragmented it. Or you might just have run out of memory, or hit a limit
enforced by the OS. No resource is *ever* infinite.
how can you get an EOF or some error
from stdin?
On most systems there is a way for the user to signal EOF on stdin. Or a
file might be being piped in to stdin.
you know, I care to know about why I should check for errors, and about
what can cause them and what I should do about it, but so far (and you
can understand that) I like to keep my code as simple as possible,
mostly that I consider that my program should work only as far as it is
used correctly (like, if a program is supposed to have a .wav file in
input, and the user put a .mp3 or anything else instead, I don't wanna
bother with doing stuff that will tell him "you need to input a .wav
file", i rather let him have a segmentation fault)


It might not cause a segmentation violation. It might overwrite critical
data instead.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Dec 9 '05 #16
Jordan Abel wrote:
On 2005-12-10, grayhag <ue***@yahoo.co m> wrote:
Eric Sosman wrote:
For efficiency's sake you'd probably want to avoid quite so many
trips in and out of the memory allocator, so a refinement would be to
start with a roomier buffer and expand by more than one character at
a time if necessary. (My own function for doing this -- everybody
writes one eventually -- begins with 100 characters and adds half the
buffer's current size each time it needs to expand: 100, 150, 225,
...)


The way it was done in K&P Programming Practice, where they started
with a one char sized buffer and doubled the size every time there was
no space left. I`s a good "golden middle" type idea, i think.


doubling it each time actually reduces the worst-case complexity [of the
entire operation] from O(n^2) to O(n). I'm not sure what complexity you
end up with adding less than the full previous size. probably something
like nlogn or n^1.5


Maybe adding a diminishing multiplier for additive part.
It`ll get lower and lower by a certain percentile
each new allocation.

--
Make it as simple as possible, but not simpler
Albert Einstein
Dec 9 '05 #17
Jordan Abel wrote:
On 2005-12-10, grayhag <ue***@yahoo.co m> wrote:
Eric Sosman wrote:

For efficiency's sake you'd probably want to avoid quite so many
trips in and out of the memory allocator, so a refinement would be to
start with a roomier buffer and expand by more than one character at
a time if necessary. (My own function for doing this -- everybody
writes one eventually -- begins with 100 characters and adds half the
buffer's current size each time it needs to expand: 100, 150, 225,
...)


The way it was done in K&P Programming Practice, where they started
with a one char sized buffer and doubled the size every time there was
no space left. I`s a good "golden middle" type idea, i think.

doubling it each time actually reduces the worst-case complexity [of the
entire operation] from O(n^2) to O(n). I'm not sure what complexity you
end up with adding less than the full previous size. probably something
like nlogn or n^1.5


Still O(n), just with a different multiplier. Assume you
start with a buffer of B characters and grow it by a fraction
r > 1 whenever it fills up. Then (ignoring the rounding off
to integer sizes), you get successive buffers of size B, B*r,
B*r^2, ... until after k expansions you eventually get to
B*r^k >= n.

You've copied (potentially) the contents of all the
smaller buffers, hence you may have copied as many as

B + B*r + B*r^2 + ... + B*r^(k-1)
= B * (r^k - 1) / (r - 1)

characters. Noting that k is log_base_r(n/B) + x, 0 <= x < 1,
the total characters copied come to:

B * (r^(log_base_r( n/B) + x) - 1) / (r - 1)
= B * (n/B * r^x - 1) / (r - 1)
= (n * r^x - B) / (r - 1)
= O(n)

"Next time, we're gonna do ... FRACTIONS!" -- Tom Lehrer

--
Eric Sosman
es*****@acm-dot-org.invalid

Dec 9 '05 #18

Flash Gordon wrote:
Michel Rouzic wrote:
Keith Thompson wrote:


<snip>
The speed of that code while reading input probably isn't going to be
much of an issue, but the multiple calls to realloc() might cause
excessive heap fragmentation, which could cause problems elsewhere in
your program. (The standard does use the term "heap", but you get the
idea.)


does it mean that the elements of my array won't be contigous?


No, it means the free space in your heap will be fragmented. Any memory
block returned by *alloc is always contiguous.


oh, thats what I thought. But, what are the consequences, I mean, I'll
have some memory occupied, some free space, and then my string, so, as
for the free space, does it mean it could only be used for something
smll enough to fit it, or otherwise it will just be wasted space?

Dec 10 '05 #19

Flash Gordon wrote:
Michel Rouzic wrote:

<snip>
"If a function be advertised to return an error code in the event of
difficulties, thou shalt check for that code, yea, even though the
checks triple the size of thy code..."

ok, I guess I should do that but.... well... as it says, it makes the
code much longer and makes it harder to read and, well, I wouldn't know
what to do with an error anyways, I mean, if the return code ain't
right, i might display something like "the return code ain't right\n"
and don't know what I should do.


If nothing else you can terminate the program with an error message
saying that it has failed.
realloc() failures? never heard of that (maybe cuz im quite new to all
that), what can happen with it?


There might not be a large enough block of free memory because you have
fragmented it. Or you might just have run out of memory, or hit a limit
enforced by the OS. No resource is *ever* infinite.
> how can you get an EOF or some error
from stdin?


On most systems there is a way for the user to signal EOF on stdin. Or a
file might be being piped in to stdin.
you know, I care to know about why I should check for errors, and about
what can cause them and what I should do about it, but so far (and you
can understand that) I like to keep my code as simple as possible,
mostly that I consider that my program should work only as far as it is
used correctly (like, if a program is supposed to have a .wav file in
input, and the user put a .mp3 or anything else instead, I don't wanna
bother with doing stuff that will tell him "you need to input a .wav
file", i rather let him have a segmentation fault)


It might not cause a segmentation violation. It might overwrite critical
data instead.


um... i dont think you know what i'm refering to. The example I took is
the one of my program that reads .wav files to deal with them, without
checking that it actually is a .wav file. basically, it will just look
at a precise place in a file for a 32-bit integer telling how many
bytes are to be read in the file. If you try to input a non .wav file
instead, the 32-bit integer read will be bogus, and is likely to have a
value much higher than the number of bytes left in the file, so the
program will try to read even after the it has read the whole file,
thus causing a segmentation fault.

so basically, as I said, if the user wants to input an mp3 file instead
of a .wav, it's at his own risk. And if you want to input an EOF
character at some point, well, it's at your own risk too, maybe one day
i'll bother with making some stuff to check that kind of foolishness,
but so far i've got more prioritary things to do than this kinda of
stuff (like making sure my program does what it's supposed to do)

Dec 10 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2404
by: Peter Kirk | last post by:
Hi there I have a form which submits a list of data to a web-application (which then saves to a database). The list consists of four input fields per row. Eg. <field_1.1><field_2.1><field_3.1><field_4.1> <field_1.2><field_2.2><field_3.2><field_4.2> <field_1.3><field_2.3><field_3.3><field_4.3> ....
6
3334
by: Thomas | last post by:
Hi, I'm having a problem with the dynamically created inputfields in Internet Explorer. The situation is the following: - I have a dynamically created table with a textbox in each Cell. - It is possible to Add and Delete rows - Some cells have special attributes (readonly and events) Here's a snippet of the code:
5
2101
by: cjl | last post by:
Hey all: This code: if (stealth) { document.searchme.query.type = 'password'; } else {
2
8379
by: crjunk | last post by:
I'm trying to find a way to create input boxes dynamically on the client side but everything that I've come across works with IE, but not FireFox. On my web page, I have the following input boxes: txtAddress1, txtCity1,txtState1, txtZip1 What I'd like to do is to have a button that says "Add Another Location". When the user clicks on the button, then txtAddress2, txtCity2, txtState2, and txtZip2 are created below the first location
1
7496
by: vega80 | last post by:
Hi. I have a problem with assigning an onkeypress-function to dynamically created input-boxes.I want to put the content of an input-field into a tag-list when the user hits enter. This works fine the first time (when the input-field is created in a non-dynamical way). The next input-field is created dynamically by a function that is called when the user hits enter (the previously generated input-field will be hidden). Then I'm trying...
1
1810
by: Steve2007 | last post by:
Hi I have the following form in my html page: <form name="mapserv" method=GET action=""> <input type="hidden" name="timeFiltering"> <input type="hidden" name="filteringType"> <input type="hidden" name="filteringBox"> <input type="hidden" name="Geofence" value="1|Geofence1|-88.19311|30.52311|-87.91011|30.65221|10|3"> <input type="hidden" name="Geofence1" value="1|Geofence1|-88.19311|30.52311|-87.91011|30.65221|10|2">
2
2541
by: Ed Jay | last post by:
I'm dynamically creating several form input elements: mValue = integer constant; for(var j = 0; j < mValue; j++) { target = "imgCn"+ j; eName = "myFile"; eName = eName+jj; document.getElementById(target).innerHTML = "<input type = 'file' name="+eName+" value=''>text"; }
1
1323
by: =?Utf-8?B?QXJuZSBHYXJ2YW5kZXI=?= | last post by:
I am programming input forms in Asp.net 2.0 Some textboxes are static on the form and viewstate works fine. Some textboxes have to be dynamically added to the form at run-time which makes viewstate difficult to maintain. Sometimes I have got viewstate to magically work. Sometime I have to manually restore viewstate. What is the best way to deal with dynamically created input boxes? -- Arne Garvander Certified Geek
4
2976
by: mohaaron | last post by:
I can think of a lot of reasons why this might need to be done but as far as I can tell it's not possible. I've been looking for a way to add HtmlTableRows to a table using a button click for a while and it seems it's not possible because the row that gets added with each click won't get recreated after a post back. After all the reading it seems that any dynamically created controls must be created in the Init event to be recreated after...
0
864
by: davidson1 | last post by:
Hai to Everybody, I am designing a website in ASP.NET , in my project students can view their information such as name,department etc... and many information for students will be displayed... all that information will be taken from database and displayed in ASP.NET so all the tables in asp.net are dynamically created , so i need give good color to dynamically created table in a proper way...... So that it good web design........ if u...
0
10311
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10080
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9942
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8967
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6733
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5378
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5509
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4043
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2874
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.