Anyone have some feedback? (C code)
#1

Hey guys, I started revisiting K&R's 2nd edition and I solved for a particular problem but I want to see if there's more efficient solutions (keep in mind that I'm only looking for solutions in C).

Here's the problem description:




And here's my solution:

https://gist.github.com/sqroot3/08ae...1c5ff41b3997e8

I am not trying to make this into a "spoonfeed me all the way" thing, its just that it's the first problem that took me some time to figure out and I'd like some more experienced C programmer's opinions on it.

Thanks!
Reply
#2

Does it also works for whitespace that's not at the beginning of a line?

Like if you have
Код:
abcd    efg
I think the 4 spaced should be replaced by a tab when tabsize is 8 or 4 (or 2 tabs when tabsize is 2). I can't test right now but I think your code does not handle that (if that's in the scope of the exercise).

I'm not very experienced in c, but I guess I would write it somewhat the same. I would just avoid else and use continue in most cases, but that's just a personal preference.

You may want to try out code review on stack exchange, it's a place where people can show their code and other people can review it. You may not get full solutions in a different way, but you will probably get some nice feedback (more than you'll get here).
Reply
#3

I like the over-documentation...
Reply
#4

Quote:
Originally Posted by yugecin
Посмотреть сообщение
Does it also works for whitespace that's not at the beginning of a line?

Like if you have
Код:
abcd    efg
I think the 4 spaced should be replaced by a tab when tabsize is 8 or 4 (or 2 tabs when tabsize is 2). I can't test right now but I think your code does not handle that (if that's in the scope of the exercise).

I'm not very experienced in c, but I guess I would write it somewhat the same. I would just avoid else and use continue in most cases, but that's just a personal preference.

You may want to try out code review on stack exchange, it's a place where people can show their code and other people can review it. You may not get full solutions in a different way, but you will probably get some nice feedback (more than you'll get here).
That case works, the code handles it in the way that it counts all non-whitespace characters and evaluates the gap based on the tabsize we defined on the top of the file - that number of non-whitespace chars, specifically this line:

Код:
if(ns >= TABSIZE - nc)
For the comment of avoid else and use continue, i assume you mean the else inside the while loop that evaluates whether one or more spaces are still "in buffer". Wouldn't using continue not allow me to put that space and decrease the space count, while the else does? Is it too much to ask if you can rewrite this with your continue method so that I can see how you'd do it?

Thanks for the reference to the site too, I'll definitely use it.

Quote:
Originally Posted by Sew_Sumi
Посмотреть сообщение
I like the over-documentation...
I like the sarcasm All joking aside, the comments are there because I posted the same code on a thread (on stackexchange) where people were solving the problem also. I agree that for production code there should be documentation like this, but perhaps separate from the source code or else it would be 100000 lines of comments per source :P
Reply
#5

Is this meant to be a text handled in server, or reading it from file ?
In case of file read, i would go for data stream instead of handling it as a text.
Would set up a search that detects a sequence of spaces in right size, replacing them by Tab, then no new lines exists, just a stream of data, much easier to handle, than reading it as text, line by line...
Reply
#6

Shhh, It wasn't sarcasm... Documentation on anything is in short supply. xD
Reply
#7

Quote:
Originally Posted by VeryTallMidget
Посмотреть сообщение
Is this meant to be a text handled in server, or reading it from file ?
In case of file read, i would go for data stream instead of handling it as a text.
Would set up a search that detects a sequence of spaces in right size, replacing them by Tab, then no new lines exists, just a stream of data, much easier to handle, than reading it as text, line by line...
It is meant to be read from the console directly, the book hasn't touched file input yet. So far, only "line inputs" have been discussed, but it seemed simpler to do it character by character rather than storing all those characters in an array, then having to change 1+, etc.

You've peaked my interest with your suggestion though so if you want to share how that would look I'd be really thankful
Reply
#8

Data Streams are more useful for larger amount of text and non-text data.
If its for text field then its already text.

Quote:
Originally Posted by Paglia
Посмотреть сообщение
You've peaked my interest with your suggestion though so if you want to share how that would look I'd be really thankful
I cannot offer code in C, because I use different language, but im 100% certain it can be done the same way in C.
Reply
#9

Quote:
Originally Posted by Paglia
Посмотреть сообщение
That case works, the code handles it in the way that it counts all non-whitespace characters and evaluates the gap based on the tabsize we defined on the top of the file - that number of non-whitespace chars, specifically this line:

Код:
if(ns >= TABSIZE - nc)
The problem is that nc is only incremented, and doesn't go down. As result this condition will always evaluate to true and always place tabs.
But I see you've updated your code so this is not applicable anymore.

I tested your updated code and this is what I got (tabsize 2, replaced tabs by a ->):
Код:
       ->->->->->
 input:  a b b c d
output:->a>bb>cd
So the result is not always correct.

Код:
  a b b c d
   ^ after this point, nchars is 1 and nspaces is 1
      'nspaces >= TABSIZE - nchars' evaluates to true, so it adds a tab
      but then, in the if block you do 'nspaces -= TABSIZE', effectively setting nspaces to -1
      so the space after the b is simply ignored (and again after the c)
Putting nspaces to 0 on line 29 (like the comment above suggests), fixes that.

Now I see this issue:
Код:
       ->->->->->
 input:  a bb b
output:->a>bb>b
             ^ this should not be a tab, but a space
Basically at every iteration of the while loop, nchars is 1 if the previous character was not a tab (except in the beginning if the line begins with (a) space(s)).
So after the space after the 2nd b, nchars is 1 and nspaces is 1, evaluating nspaces >= TABSIZE - nchars to true, so it will insert a tab incorrectly.

(I have only tested with tabsize 2 and no tabs in input so far)
(I think the comment on line 16 is wrong too, the last word should probably be 'tab' instead of 'space')

The rule for inserting a tab would be something like this (example with tabsize 2):
Код:
A tab will move the cursor to the next tab position, which is a multiple of tabsize.
So at char 0, inserting a tab will put cursor at 2.
At char 1, it will also put the cursor at 2 because that is the next tab position
At char 2, the next tab position is 4
At char 3, it will be 4 as well
etc...

->->->->->->->
  a bb c    c
->a>bb c->->c

so this is what I would do:
keep track of how many characters are added since the last tab position
when the next non-space, non-tab char is read, see if the amount
  of spaces is >= the amount of characters missing to proceed
  to the next multiple of TABSIZE. If so, insert tabs
And here's another case that doesn't work, if there are spaces followed by a tab (example tabsize 8 ):
Код:
a    -->b
that can be changed by 1 single tab
a------>b
to do that, check first if c is a tab, and if so,
  add TABSIZE (minus the tab column you're at) to nspaces and continue
I forked your gist and changed so the things I described above works.
(I also added the continue stuff I talked about, see below)

https://gist.github.com/yugecin/7ff4...0ca1e92a70bd9b
The main way of thinking in my code is to remember how many characters are added since the last tab column.

I haven't tested it thoroughly but it seems to be working for all the testcases I tried.
sample testcases (tabsize 8 ):
Код:
  aaa                          b b      b                        bbbbbbbbbbbbbbbbbbbbb          d
  aaa			       b b	b			 bbbbbbbbbbbbbbbbbbbbb		d
    	       	                  a
				  a
                     a					           b
		     a						   b
formatted with ->:
Код:
------->------->------->------->------->------->------->------->------->------->------->------->
  aaa                          b b      b                        bbbbbbbbbbbbbbbbbbbbb          d
  aaa-->------->------->       b b----->b------>------->-------> bbbbbbbbbbbbbbbbbbbbb->------->d
    --->       >                  a
------->------->------->------->  a
                     a->------->------->------->------->           b
------->------->     a->------->------->------->------->------->   b
---

Quote:
Originally Posted by Paglia
Посмотреть сообщение
For the comment of avoid else and use continue, i assume you mean the else inside the while loop that evaluates whether one or more spaces are still "in buffer". Wouldn't using continue not allow me to put that space and decrease the space count, while the else does? Is it too much to ask if you can rewrite this with your continue method so that I can see how you'd do it?
Basically your code is like this:
Код:
while (..) {
	if (..) {
		...
	} else {
		...
	}
}
and I would do
Код:
while (..) {
	if (..) {
		...
		continue;
	}

	...
}
It reduces the level of indentation in your else branch and if you're checking the code you don't need to scroll down to the point where the else branch ends to see if some other statement will execute or not, by seeing the continue you know that there's nothing more going on so you can read through more quickly (imo).
edit: this is only my opinion, of course. I'd say stick with what you think works best for you.
Reply
#10

Oh I see, thanks for such a detailed response!

Right now I have some other projects to take care of, but once I get most of them out of the way I'll return to look at these notes and your updated gist to get a better feel for what you're telling me
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)