Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Input-line reverser (http://www.velocityreviews.com/forums/t440698-input-line-reverser.html)

Albert 12-30-2005 04:21 AM

Input-line reverser
 
This not-yet-working C program's aim is to output each input line
reversed (so if the user enters 'hello', the program will output
'olleh' - and please assume this stdout and stdin!!!).
Why the h**l isn't this WORKING AND WHY DOES IT CRASH???!

#include <stdio.h>
#define MAXINPUT 256

void reverse(char[], int);

main()
{
int c;
int number;
char s[MAXINPUT];
int i;

for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n'); i++) {
s[i] = c;
++number;
}
reverse(s, number);


for (i=0; i<=number; i++)
putchar(s[i]);
return 0;
}


void reverse(char s[], int num_elements)
{
int i, j;

for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
s[i] = s[j];
}


Richard Heathfield 12-30-2005 04:27 AM

Re: Input-line reverser
 
Albert said:

> void reverse(char s[], int num_elements)
> {
> int i, j;
>
> for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
> s[i] = s[j];
> }


Desk-check it. That means: get out a piece of paper, and pretend you're a
computer. Write down the values of all objects, each at the head of its own
column. Assuming you have five elements:

Code s[0] s[1] s[2] s[3] s[4] n i j
'h' 'e' 'l' 'l' 'o' 5 ? ?

Put down each code step in the left hand column, and look at the effect the
code has on the values of all the relevant objects. For example:

Code s[0] s[1] s[2] s[3] s[4] n i j
'h' 'e' 'l' 'l' 'o' 5 ? ?
i = 0 'h' 'e' 'l' 'l' 'o' 5 0 ?
j = n-1 'h' 'e' 'l' 'l' 'o' 5 0 4
i <= 4? Yes.
j >= 0? Yes.
s[i]=s[j] 'o' 'e' 'l' 'l' 'o' 5 0 4

and so on. Doing this by hand - "desk-checking" - is an invaluable aid to
understanding what you actually wrote, as opposed to what you thought you
wrote.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Arthur J. O'Dwyer 12-30-2005 04:31 AM

Re: Input-line reverser
 

On Thu, 29 Dec 2005, Albert wrote:
>
> Why the h**l isn't this WORKING AND WHY DOES IT CRASH???!
>
> #include <stdio.h>
> #define MAXINPUT 256
>
> void reverse(char[], int);
>
> main()


int main(void)

> {
> int c;
> int number;
> char s[MAXINPUT];
> int i;
>
> for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n'); i++) {


For bonus points, consider what happens if c is EOF.

> s[i] = c;
> ++number;


What is 'number' at this point in the program? Hint: It depends
on what 'number' was at the beginning of the program. Find where you
(failed to) initialized 'number', and you'll have found the main
problem. ...Okay, one of the /two/ main problems.

> }
> reverse(s, number);
>
>
> for (i=0; i<=number; i++)
> putchar(s[i]);


What is 's[number]'? (For that matter, if you give 'number' a real
name, such as 'length', you'll probably find out why you don't need
it after all.)

> return 0;
> }
>
>
> void reverse(char s[], int num_elements)
> {
> int i, j;
>
> for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)


Once the program no longer crashes, it will be time to examine this
loop's termination condition to find out why it doesn't do anything.

> s[i] = s[j];
> }



-Arthur

Albert 12-30-2005 04:35 AM

Re: Input-line reverser
 
Could you FIRSTLY tell me why this program crashes?


Richard Heathfield 12-30-2005 04:41 AM

Re: Input-line reverser
 
Albert said:

> Could you FIRSTLY tell me why this program crashes?


Sure. It's because the program is not a valid C program. Now, you might
argue that it compiles just fine, and runs just fine except for the
crashing part, and is therefore a valid C program. But you'd be wrong.

The reason it's not a valid C program is that it attempts to modify the
value of an object, when that object hasn't been given a value yet.
Specifically, look at 'number', in main, which you define but to which you
assign no value. Therefore, that object's value is indeterminate.
Nevertheless, you try to use that value (by adding 1 to it), thus invoking
undefined behaviour, just as you would do if you were stupid enough (which,
of course, you never will be) to define main with some return type other
than int. In each case, the C language washes its hands of the program, and
so the results are arbitrary. Crashing is just one of many possibilities.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Albert 12-30-2005 04:49 AM

Re: Input-line reverser
 
I've 'desk-checked' and I still can't figure out why if I enter 'he' it
outputs 'ee'.
Could you give me another hint?

I've updated the program:

#include <stdio.h>
#define MAXINPUT 256


void reverse(char[], int);


main()
{
int c;
int number = 0;
char s[MAXINPUT];
int i;


for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n') && (c!=EOF);
i++) {
s[i] = c;
++number;
}
reverse(s, number);


for (i=0; i<=number-1; i++)
putchar(s[i]);
return 0;
}


void reverse(char s[], int num_elements)
{
int i, j;

for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
s[i] = s[j];
}


Arthur J. O'Dwyer 12-30-2005 04:51 AM

Re: Input-line reverser
 

On Thu, 29 Dec 2005, Albert wrote:
>
> Could you FIRSTLY tell me why this program crashes?


Yes. You didn't provide any 'main' function.
(Or are you talking about some other program? Why don't you provide
the program in question, or at least some context for your remark?)

If you're using Google Groups to post, *don't*. If you must, then
go Google "Google Groups Usenet" and follow the instructions you find
in re: netiquette.


Note that Richard's reply was better than mine, because /he/ wasn't
not paying enough attention to the 'reverse' function. ;) The second
half of my reply was just plain wrong.

-Arthur

Richard Heathfield 12-30-2005 04:54 AM

Re: Input-line reverser
 
Albert said:

> I've 'desk-checked' and I still can't figure out why if I enter 'he' it
> outputs 'ee'.


It's because you tell it to.

> Could you give me another hint?


Here are three hints:

You are right to start at both ends and work inward.

You should stop halfway. When i > j, you're done.

You should use a temporary object to store one of the values when swapping.

If you do s[i] = s[j], you lose the original value of s[i]. The idiom you
need is:

tmp = s[i];
s[i] = s[j];
s[j] = tmp;

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)

Chris F.A. Johnson 12-30-2005 05:21 AM

Re: Input-line reverser
 
On 2005-12-30, Albert wrote:
> I've 'desk-checked' and I still can't figure out why if I enter 'he' it
> outputs 'ee'.
> Could you give me another hint?

[snip]
> void reverse(char s[], int num_elements)
> {
> int i, j;
>
> for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
> s[i] = s[j];
> }


What are the values of s[0] and s[1] after the first iteration of
the loop?


--
Chris F.A. Johnson, author | <http://cfaj.freeshell.org>
Shell Scripting Recipes: | My code in this post, if any,
A Problem-Solution Approach | is released under the
2005, Apress | GNU General Public Licence

Mark McIntyre 12-30-2005 12:27 PM

Re: Input-line reverser
 
On 29 Dec 2005 20:35:17 -0800, in comp.lang.c , "Albert"
<albert.xtheunknown0@gmail.com> wrote:

>Could you FIRSTLY tell me why this program crashes?


When you desk-check it, you will discover the answer to that.

Really, Richard is trying to help you by explaining an important
technique in writing computer programmes. Its not all about typing on
keyboards.
Mark McIntyre
--

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----


All times are GMT. The time now is 10:52 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.