By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,778 Members | 1,997 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,778 IT Pros & Developers. It's quick & easy.

printf() and character arrays

P: n/a
Look at this code:

#include <stdio.h>

int main(void) {

char name[50];
printf("What is your name?\n");
fgets(name, sizeof(name), stdin);
printf("Your name is %s.\n", name);

return 0;

}

I get the comma on a separate line. I know why, it is
because of the '\n' at the end of "name"(that's at least what
I think, but how can I remove it?

I have another question: How do real programmers in real
programs deal with memory allocation? Previously, when
I have asked questions, people have called my programs
'toy applications', which they are, because
they don't have any memory allocation. How does a
programmer that is working on a big application with
many variables do?
Nov 14 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Eirik wrote:

Look at this code:

#include <stdio.h>

int main(void) {

char name[50];
printf("What is your name?\n");
fgets(name, sizeof(name), stdin);
printf("Your name is %s.\n", name);

return 0;

}

I get the comma on a separate line.
Comma? What comma? Am I going blind?
I know why, it is
because of the '\n' at the end of "name"(that's at least what
I think, but how can I remove it?
Search for it and replace it with '\0'. Here's one
way:

char *p;
...
p = strchr(name, '\n');
if (p != NULL)
*p = '\0';
I have another question: How do real programmers in real
programs deal with memory allocation? Previously, when
I have asked questions, people have called my programs
'toy applications', which they are, because
they don't have any memory allocation. How does a
programmer that is working on a big application with
many variables do?


"It depends."

Some applications just call malloc() and friends as
needed. Others wrap fancier application-specific memory
managers around them. Still others don't use malloc()
and friends at all, but substitute their own complete
memory management packages (of course, when they do this
they have ventured outside the territory mapped by the
Standard).

The biggest application I personally have written code
for was a relatively modest affair of about three million
source lines, ~80% C and ~20% Lisp. It used a hodgepodge
of different allocators (in entirely non-Standard fashion):

- malloc() and friends,

- system-specific APIs like sbrk() and mmap(),

- a special allocator for pools of related fixed-
size memory blocks,

- another allocator for pools of variable-size blocks,

- replacements for malloc() and friends, built atop
the variable-sized allocator,

- the memory management of the Lisp interpreter, built
atop all of the above (and, of course, including
garbage collection),

- idiosyncratic memory managers in individual subsystems,
built atop all of the above,

- ... and probably a few more I've forgotten or was never
aware of in the first place.

I'm not saying that this sort of a melange is appropriate
for all "big" applications. However, it's my impression that
many large programs chafe at the restrictions that come along
with the simplicity of malloc() and friends, and find themselves
building fancier (and less simple) memory managers to make
life easier for them. Sometimes these fancier packages use
malloc() and friends as their underpinnings, and sometimes
they don't.

--
Er*********@sun.com
Nov 14 '05 #2

P: n/a
Eirik <hx******************************@xyxaxhxoxo.no> wrote:
Look at this code:

#include <stdio.h>

int main(void) {

char name[50];
printf("What is your name?\n");
fgets(name, sizeof(name), stdin);
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0';
printf("Your name is %s.\n", name);

return 0;

}

I get the comma on a separate line. I know why, it is
because of the '\n' at the end of "name"(that's at least what
I think, but how can I remove it?


Stig

--
brautaset.org
Nov 14 '05 #3

P: n/a
nrk
Eric Sosman wrote:
Eirik wrote:

Look at this code:

#include <stdio.h>

int main(void) {

char name[50];
printf("What is your name?\n");
fgets(name, sizeof(name), stdin);
printf("Your name is %s.\n", name);

return 0;

}

I get the comma on a separate line.


Comma? What comma? Am I going blind?


Probably a daft European thing, where they say "," when they obviously mean
"." :-)

<snip>

-nrk.
Nov 14 '05 #4

P: n/a
Stig Brautaset <ne**@brautaset.org> writes:
[..]
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0';

[...]

It would be easier, or at least shorter, to provide a correct solution
than to explain why this one isn't quite correct.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
(Note new e-mail address)
Nov 14 '05 #5

P: n/a
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0'; [...]

It would be easier, or at least shorter, to provide a correct solution
than to explain why this one isn't quite correct.


How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"The trouble with the French is they don't have a word for entrepreneur."
- George Bush
Nov 14 '05 #6

P: n/a
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0'; [...] It would be easier, or at least shorter, to provide a correct solution
than to explain why this one isn't quite correct.

How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';


Huh?

This tests if the string is longer than 0, and either removes
the last character or resets the terminating NUL. What does
this have to do with anything?

What you do need to do is make sure that the last character
is '\n' and, if it is, truncate it. If it is not a newline,
then the overflow should be handled intelligently.

Alex
Nov 14 '05 #7

P: n/a
Joona I Palaste <pa*****@cc.helsinki.fi> writes:
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0';

[...]

It would be easier, or at least shorter, to provide a correct solution
than to explain why this one isn't quite correct.


How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';


I'd prefer this for removing the last character in a string in general:
if (string[0] != '\0')
name[strlen (string) - 1] = '\0';
or even:
if (string[0] != '\0')
strchr (string, '\0')[-1] = '\0';
though that may be too obscure. But for this particular case:
p = strchr (string, '\n');
if (p != NULL)
*p = '\0';
--
"When in doubt, treat ``feature'' as a pejorative.
(Think of a hundred-bladed Swiss army knife.)"
--Kernighan and Plauger, _Software Tools_
Nov 14 '05 #8

P: n/a
Alex <al*******@hotmail.com> scribbled the following:
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0';
[...] It would be easier, or at least shorter, to provide a correct solution
than to explain why this one isn't quite correct.
How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';
Huh? This tests if the string is longer than 0, and either removes
the last character or resets the terminating NUL. What does
this have to do with anything?
It has to do with my not reading the thread. There *IS* an unhandled
issue with the original code - if the string happens to be "", i.e. a
string consisting of just the terminating NUL, then the original code
causes undefined behaviour, while mine doesn't.
But that was most likely not the issue Keith was thinking about. Now
that I think of it, the possibility of the string being "" would never
arise if we use the code in the way it's presented in this thread.
What you do need to do is make sure that the last character
is '\n' and, if it is, truncate it. If it is not a newline,
then the overflow should be handled intelligently.


--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Make money fast! Don't feed it!"
- Anon
Nov 14 '05 #9

P: n/a
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:
Alex <al*******@hotmail.com> scribbled the following:
Joona I Palaste <pa*****@cc.helsinki.fi> wrote:
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
> /* this removes the last character in the array (which will be the \n
> * unless you typed in too many characters to fit in the array). It
> * would be better to test if the last character is a newline.
> */
> name[strlen(name) - 1] = '\0';
[...] It would be easier, or at least shorter, to provide a correct solution
than to explain why this one isn't quite correct. How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';
Huh? This tests if the string is longer than 0, and either removes
the last character or resets the terminating NUL. What does
this have to do with anything?
It has to do with my not reading the thread. There *IS* an unhandled
issue with the original code - if the string happens to be "", i.e. a
string consisting of just the terminating NUL, then the original code
causes undefined behaviour, while mine doesn't.


This is generally a good point, but not in the context of fgets.

If fgets does not return NULL and the length argument is larger
than 0, then the string may never end up being "".

Alex
Nov 14 '05 #10

P: n/a
Joona I Palaste wrote:
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
/* this removes the last character in the array (which will be the \n
* unless you typed in too many characters to fit in the array). It
* would be better to test if the last character is a newline.
*/
name[strlen(name) - 1] = '\0';

[...]

It would be easier, or at least shorter, to provide a correct
solution than to explain why this one isn't quite correct.


How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';


I thought the idea was to remove a (possible) terminating '\n'.

if (p = strchr(name, '\n') *p = '\0';

with suitable declarations.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #11

P: n/a
"Eirik" <hx******************************@xyxaxhxoxo.no> wrote in message news:<wv*******************@news2.e.nsc.no>...
Look at this code:

#include <stdio.h>

int main(void) {

char name[50];
printf("What is your name?\n");
fgets(name, sizeof(name), stdin);
printf("Your name is %s.\n", name);

return 0;

}

I get the comma on a separate line. I know why, it is
because of the '\n' at the end of "name"(that's at least what
I think, but how can I remove it?
char *p = strrchr (name, '\n');
if (p)
*p = 0;

strrchr() returns a pointer to the last occurrence of the newline
character in name; if the pointer is not NULL, set the value at that
location to 0. If strrchr() returns NULL, that means the newline was
not found in name. This could mean that someone typed in a name
longer than you were expecting, and that there are still characters in
the input buffer. Or it could mean that someone terminated input by
typing ^Z or ^D or something.

I have another question: How do real programmers in real
programs deal with memory allocation? Previously, when
I have asked questions, people have called my programs
'toy applications', which they are, because
they don't have any memory allocation. How does a
programmer that is working on a big application with
many variables do?


It depends on the situation. Some big applications can get by with
statically allocated memory, some get by with a mix of static and
dynamic allocation, some require extensive dynamic allocation. I
worked on a sonar simulator for the Navy (a big app, at least as far
as LOC were concerned), and it used static buffers almost exclusively.
Another project was an output manager that routed jobs throughout an
enterprise, and that required extensive dynamic memory management (job
queues could grow and shrink a great deal over the course of a day).

Right now I'm working on a C4I system for the military, and it falls
into the roughly half-and-half camp. The configuration and user
interface software rely mostly on dynamic memory management, the data
forwarding and track management software use mostly static memory.
Nov 14 '05 #12

P: n/a
CBFalconer wrote:

Joona I Palaste wrote:
Keith Thompson <ks***@mib.org> scribbled the following:
Stig Brautaset <ne**@brautaset.org> writes:
[..]
> /* this removes the last character in the array (which will be the \n
> * unless you typed in too many characters to fit in the array). It
> * would be better to test if the last character is a newline.
> */
> name[strlen(name) - 1] = '\0';
[...]

It would be easier, or at least shorter, to provide a correct
solution than to explain why this one isn't quite correct.


How about this, then?
name[strlen(name) ? strlen(name)-1 : 0] = '\0';


I thought the idea was to remove a (possible) terminating '\n'.

if (p = strchr(name, '\n') *p = '\0';

with suitable declarations.


Or, just maybe another paren for balance..

if (p = strchr(name, '\n')) *p = '\0';

...and if you want to keep gcc quiet, a couple more..

if ((p = strchr(name, '\n'))) *p = '\0';

--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 14 '05 #13

P: n/a
"Eirik" <hx******************************@xyxaxhxoxo.no> wrote in message news:<wv*******************@news2.e.nsc.no>...
Look at this code:

#include <stdio.h>

int main(void) {

char name[50];
printf("What is your name?\n");
fgets(name, sizeof(name), stdin);
printf("Your name is %s.\n", name);

return 0;

}

I get the comma on a separate line. I know why, it is
because of the '\n' at the end of "name"(that's at least what
I think, but how can I remove it?

I have another question: How do real programmers in real
programs deal with memory allocation? Previously, when
I have asked questions, people have called my programs
'toy applications', which they are, because
they don't have any memory allocation. How does a
programmer that is working on a big application with
many variables do?

Memory Management completely depends on the application, development
timelines & requirements, how the application is to be used, and
hardware available.

Dynamic memory allocation is surprisingly slow because a lot of
overhead is spent managing the heap. Some operating systems (such as
Palm OS) will even attempt to defragement the heap if a large enough
chunk is not available. Allocating and releasing small pieces
unnecessarly can also lead to fragmentation problems, particularly on
embedded devices with very little available RAM.

On the other hand, static allocation has it's own drawbacks. #1, at
best the memory is tied up as long as it is in scope, but more likely
is in use as long as the program is running. With dynamic allocation,
you can return the memory to the heap as soon as you know it is no
longer being used.

Finally, to skirt the issue of memory management all together, you may
wish to read up on garbage collectors--the most popular being part of
any Java Virtual Machine; however, that is for a separate group.
There are garbage collectors for C too, but there are good reasons
you'll be hard pressed to find a C/C++ program that uses one.

---
Jared Dykstra
http://www.bork.org/~jared
Nov 14 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.