K&R exercises

M

mdh

Hi Group,
Not looking for an answer, but more of an explanation. Thinking back
to those heady days when you had the time to do them, may I ask this.

Exercise 1-22 asks for a program to "fold" long input lines into 2 or
more shorter lines before the nth column... etc etc. Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

Not even sure if I should have asked this, but anyway.....


Tks
 
R

Roberto Waltman

Not looking for an answer, but more of an explanation.
...
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

<off-topic>
Simple:

(a) Some devices (printers) do not process tabs - They may ignore
them, or print only one space, etc. In a modern computer/OS the
printer driver will perform the tab expansion automatically, but for
other devices you need to do it as a separate step.

(b) I use 4 column tab stops in my code. Some of my colleagues use 3
or 8. (Yes, we should have coding standards for that, but that is a
separate story) Code carefully and beautifully formatted in somebody's
screen, looks terrible when somebody looks at it with different
default settings in his/her editor. Unless you use spaces instead of
tabs.
</off-topic>
 
M

mdh

Roberto said:

<OT>

thank you Roberto...yes...I realize that the text is a bit old...but it
sure is a thrill to go back to the masters.

Thanks for that explantation.

<OT>
 
D

Diomidis Spinellis

mdh said:
Not looking for an answer, but more of an explanation. Thinking back
to those heady days when you had the time to do them, may I ask this.

Exercise 1-22 asks for a program to "fold" long input lines into 2 or
more shorter lines before the nth column... etc etc. Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

At some point you'll need to convert tabs into spaces in order to
display them. This might be in the firmware of the terminal or printer,
the code of the terminal emulator window, or the display function of the
editor. For example, the following excerpt from the NetBSD kernel
terminal handling code converts tabs into spaces when output is going
into a device that can't handle tabs on its own:

if (c == '\t' &&
ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
c = 8 - (tp->t_column & 7);
notout = b_to_q(" ", c, &tp->t_outq);
 
F

Fred Kleinschmidt

mdh said:
Hi Group,
Not looking for an answer, but more of an explanation. Thinking back
to those heady days when you had the time to do them, may I ask this.

Exercise 1-22 asks for a program to "fold" long input lines into 2 or
more shorter lines before the nth column... etc etc. Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

Not even sure if I should have asked this, but anyway.....


Tks
Say you are displaying a page on the screen, in a window that can handle
80 columns (of non-proportional font), and are not using a horizontal
scrollbar. Or say you have a screen that can display a maximum of 80
columns, and does not wrap.

If a line has several tabs in it, you have to expand those tabs into the
appropriate number of blanks in order to decide when to "fold" the
line, so that the user can see the text. Otherwise it is off screen.
 
P

Pedro Graca

mdh said:
Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

Not even sure if I should have asked this, but anyway.....

Suppose I have my tabs set to eight spaces

#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */
printf("Hello, %s!", name); /* greet user */
return 0; /* and exit */
}

and Louise, who prefers three spaced tabs, opens my source file

#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */
printf("Hello, %s!", name); /* greet user */
return 0; /* and exit */
}

So if there's a chance Louise will see my code, I'd rather make her have
some extra work to format the coding to her liking, than to have her see
that mess you see up there :)
 
S

Skarmander

Roberto Waltman wrote:
(b) I use 4 column tab stops in my code. Some of my colleagues use 3
or 8. (Yes, we should have coding standards for that, but that is a
separate story) Code carefully and beautifully formatted in somebody's
screen, looks terrible when somebody looks at it with different
default settings in his/her editor. Unless you use spaces instead of
tabs.

Carefully, beautifully and (as I infer) *manually* formatting code is a
tremendous waste of time, and as you've discovered, it's not a stable process.

If you use tabs, use them for logical indentation, not to produce a
particular amount of whitespace, and your formatting problems vanish into
thin air. For all the rest there's pretty printers, or, in these modern
times, IDEs with autoformatting.

This is more on topic in this newsgroup than others, as C programmers have a
long and venerable tradition of formatting code in a myriad different ways,
each superior to the others. One shudders to think at the amount of
productive coding time that must have been wasted by people laying out their
source code to look good on their monitors, only to be tempted to do it all
over again when they change tab sizes, monitors, or personal predilections.

Hm. If this sounds like a flame to you, please ignore it. Formatting issues
rarely spawn productive discussions, but I had to get it out of my system.

S.
 
P

Pedro Graca

Pedro Graca forgot the '\n' on the printf() call:
#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */

#if 0
printf("Hello, %s!", name); /* greet user */
#endif
printf("Hello, %s!\n", name); /* greet user */
 
K

Keith Thompson

Pedro Graca said:
mdh said:
Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

Not even sure if I should have asked this, but anyway.....

Suppose I have my tabs set to eight spaces

#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */
printf("Hello, %s!", name); /* greet user */
return 0; /* and exit */
}

and Louise, who prefers three spaced tabs, opens my source file

#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */
printf("Hello, %s!", name); /* greet user */
return 0; /* and exit */
}

So if there's a chance Louise will see my code, I'd rather make her have
some extra work to format the coding to her liking, than to have her see
that mess you see up there :)

I *never* set tabstops to anything other than 8 (so things look
correct when printed or viewed with any text viewing program), but I
usually use 4-column indentation. My editor (vi) automatically uses a
combination of tabs and spaces for indentation. (And then I usually
expand tabs to spaces myself.)
 
O

ozbear

Hi Group,
Not looking for an answer, but more of an explanation. Thinking back
to those heady days when you had the time to do them, may I ask this.

Exercise 1-22 asks for a program to "fold" long input lines into 2 or
more shorter lines before the nth column... etc etc. Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

Not even sure if I should have asked this, but anyway.....


Tks
[OT]
I had to do this preprocessing of tab stops-to-spaces for some ASCII
files that were being FTP'ed to another system in ASCII mode of some
C source files. The tab stops were set in the editor to every 4
columns but either the FTP client or the server (not sure which now,
was a long time ago) expanded tab stops itself, and to every 8
columns, making a mess of the sources.

Oz
 
R

Roberto Waltman

ozbear said:
The tab stops were set in the editor to every 4
columns but either the FTP client or the server (not sure which now,
was a long time ago) expanded tab stops itself, and to every 8
columns, making a mess of the sources.

Because of this and other similar annoyances, a former employer coding
standard specifically prohibited the use of tabs for indentation, a
practice I have adopted.

Even if everybody is using the same indentation and tab stop settings,
if you have, for example, 4 col indentation and 8 col hard tab stops,
like in Keith's post, things like adding a line number at the start of
every line before printing, (common practice for code reviews,) may
break havoc with the formatting.
 
R

Roberto Waltman

Skarmander said:
Roberto Waltman wrote:
Code carefully and beautifully formatted in somebody's

Carefully, beautifully and (as I infer) *manually* formatting code is a
tremendous waste of time, and as you've discovered, it's not a stable process.

If you use tabs, use them for logical indentation, not to produce a
particular amount of whitespace, and your formatting problems vanish into
thin air. For all the rest there's pretty printers, or, in these modern
times, IDEs with autoformatting.

I typed that "keyboard in cheek." Of course I use "tabs" for logical
indentation, (as in, press the tab key at the beginning of that line,
indent that line; select a group of lines or a C block, press tab,
indent the whole block; press shift-tab or whatever, un-indent the
whole block etc.) But after configuring my editor, I trust it to never
insert an actual tab character in the file. Otherwise the formatting
problems do not "vanish into thin air", because the presence of tabs
is what created them in the first place. (And yes, I use programs as
astyle and indent, or whatever the IDE du jour will provide)
This is more on topic in this newsgroup than others, as C programmers have a
long and venerable tradition of formatting code in a myriad different ways,
each superior to the others. One shudders to think at the amount of
productive coding time that must have been wasted by people laying out their
source code to look good on their monitors, only to be tempted to do it all
over again when they change tab sizes, monitors, or personal predilections.

I agree. I am fighting this at work now. In one of the projects I am
working now, I adopted the style of one of my colleagues to make sure
she will not waste time reformatting my code to her liking when she
has to use it.
Hm. If this sounds like a flame to you, please ignore it. Formatting issues
rarely spawn productive discussions, but I had to get it out of my system.

Nope. I strongly believe that adherence to coding standards (covering
much more than indentation style) does indeed help to produce better
quality software. For any project involving more than one programmer,
it makes much easier to understand, integrate, reuse, test, etc. each
others code.

Tell it to one of my colleagues, that likes to declare macros that
expand to function declarators + the initial brace of a function body.
[ /* this is a complete function */ MACRO statement; statement; ... }
] This makes the code more difficult to read in addition to breaking
the functionality of pretty-printers and editors that allow you to
jump to the beginning of a block, or function, etc.

Or to another, that always puts a return statement at the end of void
functions, and adds this line to the end of every file:
/**************** end of file *********************/
(I guess I should be grateful, that stops me from going on editing
vacuum...)

Or to another, that the only comments that he ever uses are like this:
/* these lines changed by ???? */
/* end of changed lines */
Information I can easily get from CVS, and totally useless to
understand the reasons for the code changes.

I guess I had to get this out of my system too ...
 
S

Skarmander

Roberto said:
I typed that "keyboard in cheek." Of course I use "tabs" for logical
indentation, (as in, press the tab key at the beginning of that line,
indent that line; select a group of lines or a C block, press tab,
indent the whole block; press shift-tab or whatever, un-indent the
whole block etc.) But after configuring my editor, I trust it to never
insert an actual tab character in the file. Otherwise the formatting
problems do not "vanish into thin air", because the presence of tabs
is what created them in the first place. (And yes, I use programs as
astyle and indent, or whatever the IDE du jour will provide)
Actually, I do use tabs, and I never run into trouble, as long as people who
think indentation is for lining up things do not pass by and hack my source
(you see the fatal flaw in this approach). That is, I use *one* tab to
indent blocks *and nothing else*. If this style is followed the source will
look "correct" regardless of the tab settings (well, as long as a tab is not
invisible, obviously). Whether you like to see 2, 3, 4 or 8 spaces, or even
tab stops, doesn't matter.

The great evil is using *both* tabs and spaces, which does not work, ever
(one of Python's great sources of trouble is not its semantic white space,
but the fact that it allows both tabs and spaces in a misplaced gesture of
tolerance). People usually eschew tabs because "tabs for logical indent
only" idea is rarely strictly adhered to, so the mixing of tabs and spaces
becomes inevitable, and everybody loses.

With regret I've recently configured my editor to replace tabs with spaces
on saving, since I've pretty much lost the battle against the space-tweaking
hordes -- although I do not like losing the "one tab = one indent level"
idea (which allows for easy formatting to just about anything).

Tell it to one of my colleagues, that likes to declare macros that
expand to function declarators + the initial brace of a function body.
[ /* this is a complete function */ MACRO statement; statement; ... }
] This makes the code more difficult to read in addition to breaking
the functionality of pretty-printers and editors that allow you to
jump to the beginning of a block, or function, etc.
Now that is pretty bletcherous. I'm glad I've never had to work with someone
capable of ignoring boundaries so casually. :)
Or to another, that always puts a return statement at the end of void
functions, and adds this line to the end of every file:
/**************** end of file *********************/
(I guess I should be grateful, that stops me from going on editing
vacuum...)
All those stars remind me of those info boxes people sometimes put at the
beginning of the file -- you know the ones, that tell you the name of the
file, the company, the authors, the last modification date, the phase of the
moon and last but not least the (always incomplete) version history, as a
poor man's version control. Great care is usually taken to make those star
boxes look nice, although that never stops them from getting out of date.
Or to another, that the only comments that he ever uses are like this:
/* these lines changed by ???? */
/* end of changed lines */
Information I can easily get from CVS, and totally useless to
understand the reasons for the code changes.
As per above, be glad you *have* CVS. The programmer in question may have
gotten used to environments where no versioning system was available. These
harsh conditions often lead to improvised tools for survival...

S.
 
A

Al Balmer

Actually, I do use tabs, and I never run into trouble, as long as people who
think indentation is for lining up things

Ah, this *is* comp.lang.c, not comp.lang.python ;-)
do not pass by and hack my source

Precisely the problem. If no-one but yourself ever uses your source,
who cares what you use?
(you see the fatal flaw in this approach). That is, I use *one* tab to
indent blocks *and nothing else*. If this style is followed the source will
look "correct" regardless of the tab settings (well, as long as a tab is not
invisible, obviously). Whether you like to see 2, 3, 4 or 8 spaces, or even
tab stops, doesn't matter.

The great evil is using *both* tabs and spaces, which does not work, ever
(one of Python's great sources of trouble is not its semantic white space,
but the fact that it allows both tabs and spaces in a misplaced gesture of
tolerance). People usually eschew tabs because "tabs for logical indent
only" idea is rarely strictly adhered to, so the mixing of tabs and spaces
becomes inevitable, and everybody loses.

With regret I've recently configured my editor to replace tabs with spaces
on saving, since I've pretty much lost the battle against the space-tweaking
hordes -- although I do not like losing the "one tab = one indent level"
idea (which allows for easy formatting to just about anything).

Why? A good editor will allow you to use the tab key (and shift-tab)
just as you have been, while actually inserting spaces.
Tell it to one of my colleagues, that likes to declare macros that
expand to function declarators + the initial brace of a function body.
[ /* this is a complete function */ MACRO statement; statement; ... }
] This makes the code more difficult to read in addition to breaking
the functionality of pretty-printers and editors that allow you to
jump to the beginning of a block, or function, etc.
Now that is pretty bletcherous. I'm glad I've never had to work with someone
capable of ignoring boundaries so casually. :)
Or to another, that always puts a return statement at the end of void
functions, and adds this line to the end of every file:
/**************** end of file *********************/
(I guess I should be grateful, that stops me from going on editing
vacuum...)
All those stars remind me of those info boxes people sometimes put at the
beginning of the file -- you know the ones, that tell you the name of the
file, the company, the authors, the last modification date, the phase of the
moon and last but not least the (always incomplete) version history, as a
poor man's version control. Great care is usually taken to make those star
boxes look nice, although that never stops them from getting out of date.
Or to another, that the only comments that he ever uses are like this:
/* these lines changed by ???? */
/* end of changed lines */
Information I can easily get from CVS, and totally useless to
understand the reasons for the code changes.

I maintain a large amount of legacy code. These comment blocks are the
first thing to go when I work on a program. They're misleading and
interrupt the flow of the real code. I've seen some that went on for
pages, and caused a great deal of trouble for colleagues using editors
which don't display comments differently (I have mine set to
color-code them in green.) It's frustrating to spend time fixing a bug
 
K

Keith Thompson

Roberto Waltman said:
Because of this and other similar annoyances, a former employer coding
standard specifically prohibited the use of tabs for indentation, a
practice I have adopted.

Even if everybody is using the same indentation and tab stop settings,
if you have, for example, 4 col indentation and 8 col hard tab stops,
like in Keith's post, things like adding a line number at the start of
every line before printing, (common practice for code reviews,) may
break havoc with the formatting.

Agreed. In the past, I've used line-numbering programs that insert
exactly 8 columns at the beginning of each line, so 8-column tab stops
won't be affected. But I find it easier to avoid tabs altogether.
For one thing, tabs often show up inconsistently; one line might start
with a tab, and the next might start with 8 spaces, and this can
change arbitrarily as the file is edited. This makes file comparisons
(diff) more difficult, and wastes space in revision control systems
such as CVS.

<OT>The version of vi I use insists on using tabs for indentation
whenever it can, but I have a two-keystroke macro that filters the
current editor buffer through "expand", and I've developed the habit
of invoking it before saving the file.</OT>

<EVEN_MORE_OT>Unfortunately, tabs are (nearly) required in
Makefiles.</EVEN_MORE_OT>
 
B

Ben C

The great evil is using *both* tabs and spaces, which does not work,
ever (one of Python's great sources of trouble is not its semantic
white space, but the fact that it allows both tabs and spaces in a
misplaced gesture of tolerance). People usually eschew tabs because
"tabs for logical indent only" idea is rarely strictly adhered to, so
the mixing of tabs and spaces becomes inevitable, and everybody loses.

There is a quite common convention for mixing tabs and spaces in C
source files which is to assume a tabstop of 8, and to use tab
characters for every sequence of 8 columns' worth of whitespace at the
start of lines. i.e. as if you'd done everything with spaces and then
s/^ {8}/\t/g on every line. So if you use an indent level of 4 columns,
you'd get four spaces for one level of indent, and then a tab for two
levels.
 
K

Keith Thompson

Ben C said:
There is a quite common convention for mixing tabs and spaces in C
source files which is to assume a tabstop of 8, and to use tab
characters for every sequence of 8 columns' worth of whitespace at the
start of lines. i.e. as if you'd done everything with spaces and then
s/^ {8}/\t/g on every line. So if you use an indent level of 4 columns,
you'd get four spaces for one level of indent, and then a tab for two
levels.

Which is what vi does by default; it has separate settings for tabstop
size and indentation level. If you think that's a bad idea, I won't
argue with you, but you will need to deal with code that was created
in vi.

Many problems can be avoided by consistently using 8-column tabstops.
Even more problems can be avoided by not using tabs at all.
 
B

Bill Pursell

Pedro said:
mdh said:
Now, there are
numerous anwers on the web and in the "C answer book", which includes a
function to expand the tabs to blanks ( depending upon where the tab is
in relationship to the next tab-stop). I have been trying to understand
why one would do this....why not just leave the tabs alone.

Not even sure if I should have asked this, but anyway.....

Suppose I have my tabs set to eight spaces

#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */
printf("Hello, %s!", name); /* greet user */
return 0; /* and exit */
}

and Louise, who prefers three spaced tabs, opens my source file

#include <stdio.h>
int main(void) {
char name[30]; /* user's name */
fgets(name, 30, stdin); /* needs error checking */
printf("Hello, %s!", name); /* greet user */
return 0; /* and exit */
}

So if there's a chance Louise will see my code, I'd rather make her have
some extra work to format the coding to her liking, than to have her see
that mess you see up there :)

That mess can be avoided if you follow the convention of using tabs
only for white space at the beginning of the line, and spaces for other
white space.

I used to follow that convention, but I've changed to using only
spaces for the following 2 reasons:
1) I thought that people who preferred indentation other than 4
spaces (which is what I like) would simply change the tapstop
setting in their editor, but I discovered that many people don't even
learn their editor well enough to know how to do that. I don't
understand how these people function, but they exist, and
are more prevalent that you might think.
2) If you expect people to modify their tabstop to change the
indentation level, you still have to assume an 8 space indentation
in terms of keeping your line-lengths under 78...so there's just no
point. Use spaces and indent as you like...just make sure your
indentation spacing is a power of 2. (ie, don't indent with
3 spaces....it's just wrong!)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,503
Latest member
supremedee

Latest Threads

Top