473,405 Members | 2,287 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

printf() and character arrays

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
13 9752
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
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
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
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
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
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
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
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
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
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
"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
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
"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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Peter Ammon | last post by:
It's my understanding that the printf() function is declared as int printf(const char * restrict format, ...); in stdio.h. And loosely speaking, if a parameter is declared as restricted, then...
4
by: sushant | last post by:
hi why do we use '&' operator in scanf like scanf("%d", &x); but why not in printf() like printf("%d" , x); thnx in advance sushant
7
by: teachtiro | last post by:
Hi, 'C' says \ is the escape character to be used when characters are to be interpreted in an uncommon sense, e.g. \t usage in printf(), but for printing % through printf(), i have read that %%...
188
by: infobahn | last post by:
printf("%p\n", (void *)0); /* UB, or not? Please explain your answer. */
27
by: jacob navia | last post by:
Has anyone here any information about how arrays can be formatted with printf? I mean something besides the usual formatting of each element in a loop. I remember that Trio printf had some...
36
by: Debaser | last post by:
I've recently read in one of my old C books that puts() is a better function call with regard to performance than printf() in the following situation: puts("Some random text"); vs. ...
40
by: somenath | last post by:
Hi All, I have one question regarding the behavior of printf function. In page number of 154 in K&R2 in Table 7-1 it is stated that Characters Argument Type :...
3
by: Ioannis Vranos | last post by:
Is printf("%ls") for printing wchar_t strings defined in C90, or it was added in C95?
15
by: Ioannis Vranos | last post by:
I recall from previous discussions here, that we must cast a non-void pointer to void * before printing its value with printf("%p"). Is it true, and if yes why?
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...
0
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...
0
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.