473,511 Members | 15,477 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

K&R2, exercise 1-19

i am not able to make it work. it compiles without any error but does
not work:

what i WANTED:

1.) 1st we will take the input in to an array. (calling "getline" in
"main")
2.) we will print that input array on terminal. (in "main")
3.) we will reverse the array. (calling "reverse" in "main")
4.) we will print that reversed array. (in "main")
what i GET:

rather than printing the reversed array, it prints an "unprintable
character" on the screen:

------------- PROGRAMME ------------------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];

for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = 0;
while(getline(arr))
{
printf("\n---------------\n%s", arr);
reverse(arr);
printf("\n ****** \n%s\n", arr);
}
return 0;

}
int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; 9 < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
+i)
arr[i] = c;

if(c == '\n')
arr[i++] = c;

arr[i] = '\0';

return i;
}
void reverse(char arr[])
{
int i = 0;
int j = MAXLENGTH - 1;
char rev_arr[MAXLENGTH - 1];

while(i < MAXLENGTH - 1)
rev_arr[i++] = arr[j--];

for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = rev_arr[i];

}

-------------- OUTPUT --------------------
[arch@voodo kr2]$ gcc -ansi -pedantic -Wall -Wextra -O ex_1-19.c
[arch@voodo kr2]$ ./a.out
like this

---------------
like this

******
?
[arch@voodo kr2]$

Apr 6 '07 #1
16 1706
On Apr 5, 10:00 pm, "arnuld" <geek.arn...@gmail.comwrote:
i am not able to make it work. it compiles without any error but does
not work:

what i WANTED:

1.) 1st we will take the input in to an array. (calling "getline" in
"main")
2.) we will print that input array on terminal. (in "main")
3.) we will reverse the array. (calling "reverse" in "main")
4.) we will print that reversed array. (in "main")

what i GET:

rather than printing the reversed array, it prints an "unprintable
character" on the screen:

------------- PROGRAMME ------------------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];

for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = 0;

while(getline(arr))
{
printf("\n---------------\n%s", arr);
reverse(arr);
printf("\n ****** \n%s\n", arr);
}

return 0;

}

int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; 9 < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
+i)
arr[i] = c;

if(c == '\n')
arr[i++] = c;

arr[i] = '\0';

return i;

}

void reverse(char arr[])
{
int i = 0;
int j = MAXLENGTH - 1;
char rev_arr[MAXLENGTH - 1];

while(i < MAXLENGTH - 1)
rev_arr[i++] = arr[j--];
If you typed in 'hi' then arr will contain:
[h][i][0]
followed by MAXLENGTH-3 garbage characters.

Also, you are supposed to reverse the string in place.

Hint:
call strlen() to find out how big it is.
for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = rev_arr[i];

}

-------------- OUTPUT --------------------
[arch@voodo kr2]$ gcc -ansi -pedantic -Wall -Wextra -O ex_1-19.c
[arch@voodo kr2]$ ./a.out
like this

---------------
like this

******
?
[arch@voodo kr2]$

Apr 6 '07 #2
On Apr 6, 10:26 am, "user923005" <dcor...@connx.comwrote:

If you typed in 'hi' then arr will contain:
[h][i][0]
i think you meant: [h][i][\0]
followed by MAXLENGTH-3 garbage characters.
what does that mean ?

[garbage][h][i][\0] OR [h][i][\0][garbage]

Also, you are supposed to reverse the string in place.
i am doing it but it is not working
Hint:
call strlen() to find out how big it is.
can't, K&R2 have not discussed "strlen()" yet.
for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = rev_arr[i];
}
-------------- OUTPUT --------------------
[arch@voodo kr2]$ gcc -ansi -pedantic -Wall -Wextra -O ex_1-19.c
[arch@voodo kr2]$ ./a.out
like this
---------------
like this
******
?
[arch@voodo kr2]$
please don't top post, it confuses me

Apr 6 '07 #3
i have changed it a little bit now it doe snot print any "unprintable
characters" but it also does not print *anything*:

------------ PROGRAMME ------------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];

for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = 0;
while(getline(arr))
{
reverse(arr);
printf("\n ****** \n%s\n", arr);
}
return 0;

}
int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; 9 < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
+i)
arr[i] = c;

if(c == '\n')
arr[i++] = c;

arr[i] = '\0';

return i;
}
void reverse(char arr[])
{
int i = 0;
int j = MAXLENGTH - 1;
char rev_arr[MAXLENGTH - 1];

for(i=0; i < j; ++i)
rev_arr[i] = 0;

while(j-- != '\0')
;

while(j >= 0)
rev_arr[i++] = arr[j--];
for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = rev_arr[i];

}

--------- OUTPUT -------------
[arch@voodo kr2]$ gcc -ansi -pedantic -Wall -Wextra -O ex_1-19.c
[arch@voodo kr2]$ ./a.out
like this

******

and

******

[arch@voodo kr2]$

Apr 6 '07 #4

"arnuld" <ge*********@gmail.comwrote in message
news:11**********************@w1g2000hsg.googlegro ups.com...
>On Apr 6, 10:26 am, "user923005" <dcor...@connx.comwrote:

>If you typed in 'hi' then arr will contain:
[h][i][0]

i think you meant: [h][i][\0]
>followed by MAXLENGTH-3 garbage characters.

what does that mean ?

[garbage][h][i][\0] OR [h][i][\0][garbage]
The latter.
>
>Also, you are supposed to reverse the string in place.

i am doing it but it is not working
Actually, you're not. In-place means only using additional storage of
constant size; you are using additional storage of size O(n).
>
>Hint:
call strlen() to find out how big it is.

can't, K&R2 have not discussed "strlen()" yet.
Then you need to find it in some other way. Hint: the string ends with
'\0'...

--
Jonas
Apr 6 '07 #5
On Apr 6, 1:47 pm, "Jonas" <spamhereple...@gmail.comwrote:
"arnuld" <geek.arn...@gmail.comwrote in message

news:11**********************@w1g2000hsg.googlegro ups.com...
On Apr 6, 10:26 am, "user923005" <dcor...@connx.comwrote:
If you typed in 'hi' then arr will contain:
[h][i][0]
i think you meant: [h][i][\0]
followed by MAXLENGTH-3 garbage characters.
what does that mean ?
[garbage][h][i][\0] OR [h][i][\0][garbage]

The latter.
Also, you are supposed to reverse the string in place.
i am doing it but it is not working

Actually, you're not. In-place means only using additional storage of
constant size; you are using additional storage of size O(n).
Hint:
call strlen() to find out how big it is.
can't, K&R2 have not discussed "strlen()" yet.

Then you need to find it in some other way. Hint: the string ends with
'\0'...
OK.. i just corrected it and it runs fine, except one problem. see the
output for that, OOPS! i see your name there ;-)

-------- PROGRAMME ----------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);
int arr_size(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];

for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = 0;
while(getline(arr))
{
reverse(arr);
printf("array size: %d\n", arr_size(arr));
printf("\nREVERSED INPUT: %s\n", arr);
}
return 0;

}
int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; i < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
+i)
arr[i] = c;

if(c == '\n')
arr[i++] = c;

arr[i] = '\0';

return i;
}
void reverse(char arr[])
{
int i = 0;
int size = arr_size(arr);
int j = size - 1;
char rev_arr[size];

for(i=0; i < size; ++i)
rev_arr[i] = 0;

for(j = size, i = 0; j >= 0; --j, ++i)
rev_arr[i] = arr[j];

rev_arr[i] = '\0';

/* now j is 0 (zero) again */
while((arr[j] = rev_arr[j++]) != '\0')
;

}
int arr_size(char arr[])
{
int i = 0;

for(i = 0; arr[i] != '\0'; ++i)
;

return (i - 1);

}

--------- OUTPUT ---------
[arch@voodo kr2]$ gcc -ansi -pedantic -Wall -Wextra -O ex_1-19.c
ex_1-19.c: In function 'reverse':
ex_1-19.c:61: warning: ISO C90 forbids variable-size array 'rev_arr'
[arch@voodo kr2]$ ./a.out
like this
array size: 9

REVERSED INPUT:
siht ekil
Jonas
array size: 5

REVERSED INPUT:
sanoJ
[arch@voodo kr2]$

Apr 6 '07 #6

"arnuld" <ge*********@gmail.comwrote in message
news:11**********************@b75g2000hsg.googlegr oups.com...
>On Apr 6, 1:47 pm, "Jonas" <spamhereple...@gmail.comwrote:
"arnuld" <geek.arn...@gmail.comwrote in message
>Also, you are supposed to reverse the string in place.
i am doing it but it is not working

Actually, you're not. In-place means only using additional storage of
constant size; you are using additional storage of size O(n).
>Hint:
call strlen() to find out how big it is.
can't, K&R2 have not discussed "strlen()" yet.

Then you need to find it in some other way. Hint: the string ends with
'\0'...

OK.. i just corrected it and it runs fine, except one problem. see the
output for that, OOPS! i see your name there ;-)
:-)
>
-------- PROGRAMME ----------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);
int arr_size(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];
If you replace MAXLENGTH - 1 with MAXLENGTH everywhere you've used it,
you'll be fine and your code will look better :)
>
for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = 0;
while(getline(arr))
{
reverse(arr);
printf("array size: %d\n", arr_size(arr));
printf("\nREVERSED INPUT: %s\n", arr);
}
return 0;

}
int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; i < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
+i)
arr[i] = c;

if(c == '\n')
arr[i++] = c;

arr[i] = '\0';

return i;
}
void reverse(char arr[])
{
int i = 0;
int size = arr_size(arr);
int j = size - 1;
char rev_arr[size];
Note that variable size arrays are only available in C99. This makes your
program less portable.
>
for(i=0; i < size; ++i)
rev_arr[i] = 0;
Not necessary, since all these zeroes will be overwritten in the next
for-loop.
>
for(j = size, i = 0; j >= 0; --j, ++i)
j = size? j is initialized correctly above. How about

for(i = 0; i < size; --j, ++i)

rev_arr[i] = arr[j];

rev_arr[i] = '\0';

/* now j is 0 (zero) again */
while((arr[j] = rev_arr[j++]) != '\0')
;

}
The reason this works is that two wrongs make a right :-) arr_size() does
not return the correct length, and j is not correctly initialized in the
second for-loop.

However, you are still not reversing the string in-place. To do this you
must reverse the string by swapping characters in the string arr itself,
without copying them to rev_arr.
>

int arr_size(char arr[])
{
int i = 0;

for(i = 0; arr[i] != '\0'; ++i)
;

return (i - 1);

}
Fine, except the result is 1 off: Simply return i, not i - 1. Also, arr_size
isn't the best name for the function, my_strlen or smth like it might be be
more appropriate to describe what it does. And, since you don't modify the
string, it should be const:

int my_strlen(const char str[]);

--
Jonas
Apr 6 '07 #7
On Apr 6, 4:51 pm, "Jonas" <spamhereple...@gmail.comwrote:
"arnuld" <geek.arn...@gmail.comwrote in message
Note that variable size arrays are only available in C99. This makes your
program less portable.
OK, i have changed that with MAXLENGTH
for(i=0; i < size; ++i)
rev_arr[i] = 0;

Not necessary, since all these zeroes will be overwritten in the next
for-loop.
i thought it is a good coding practice to initialise an array. BTW,
what does the array contain without initialisation of its elements.
GARBAGE ?

for(j = size, i = 0; j >= 0; --j, ++i)

j = size? j is initialized correctly above. How about

for(i = 0; i < size; --j, ++i)
look much better, changed ....
rev_arr[i] = arr[j];
rev_arr[i] = '\0';
/* now j is 0 (zero) again */
while((arr[j] = rev_arr[j++]) != '\0')
;
}
The reason this works is that two wrongs make a right :-)
:-(
arr_size() does not return the correct length,
i changed the "return (i - 1)" to "return i". OK ?

and j is not correctly initialized in the second for-loop.
did "j = 0" just above the loop.
However, you are still not reversing the string in-place. To do this you
must reverse the string by swapping characters in the string arr itself,
without copying them to rev_arr.
i tried this but it EATS the words:

void reverse2(char arr[])
{
int i = 0;
int j = my_strln(arr) - 1;

while(arr[i] != '\0')
arr[i++] = arr[j--];
}

i am not able to think of any other solution except copying of array
elements.
Fine, except the result is 1 off: Simply return i, not i - 1. Also, arr_size
isn't the best name for the function, my_strlen or smth like it might be be
more appropriate to describe what it does. And, since you don't modify the
string, it should be const:

int my_strlen(const char str[]);
thanks, code modified to show this :-)

Apr 6 '07 #8

"arnuld" <ge*********@gmail.comwrote in message
news:11**********************@l77g2000hsb.googlegr oups.com...
>On Apr 6, 4:51 pm, "Jonas" <spamhereple...@gmail.comwrote:
>"arnuld" <geek.arn...@gmail.comwrote in message
>Note that variable size arrays are only available in C99. This makes your
program less portable.

OK, i have changed that with MAXLENGTH
for(i=0; i < size; ++i)
rev_arr[i] = 0;

Not necessary, since all these zeroes will be overwritten in the next
for-loop.

i thought it is a good coding practice to initialise an array. BTW,
what does the array contain without initialisation of its elements.
GARBAGE ?
Yep. And you should initialize variables, but that is exactly what you do in
the next for-loop. no need to first set it to zero and then something else,
as long as you know that it will be initialized.
>
for(j = size, i = 0; j >= 0; --j, ++i)

j = size? j is initialized correctly above. How about

for(i = 0; i < size; --j, ++i)

look much better, changed ....
rev_arr[i] = arr[j];
rev_arr[i] = '\0';
/* now j is 0 (zero) again */
while((arr[j] = rev_arr[j++]) != '\0')
;
}
>The reason this works is that two wrongs make a right :-)

:-(
>arr_size() does not return the correct length,

i changed the "return (i - 1)" to "return i". OK ?

>and j is not correctly initialized in the second for-loop.

did "j = 0" just above the loop.
j was originally initialized to size - 1, which was fine.

>
>However, you are still not reversing the string in-place. To do this you
must reverse the string by swapping characters in the string arr itself,
without copying them to rev_arr.

i tried this but it EATS the words:

void reverse2(char arr[])
{
int i = 0;
int j = my_strln(arr) - 1;

while(arr[i] != '\0')
arr[i++] = arr[j--];
}
Think through what is happening here. What you need to do is to swap
characters in the string.
--
Jonas
Apr 6 '07 #9
On Apr 6, 6:37 pm, "Jonas" <spamhereple...@gmail.comwrote:
arnuld wrote:
j was originally initialized to size - 1, which was fine.

BUT value of "j" changed in the previous loops, that is why i set it
to 0 again , not assuming it is zero.

i tried this but it EATS the words:
void reverse2(char arr[])
{
int i = 0;
int j = my_strln(arr) - 1;
while(arr[i] != '\0')
arr[i++] = arr[j--];
}
Think through what is happening here. What you need to do is to swap
characters in the string.
i tried but it did not work, since 8 AM this morning i am working on
it with another programme, i will looked at the solution of Richard
Heithfield and understood will try to understand.

Apr 6 '07 #10
On Apr 6, 6:37 pm, "Jonas" <spamhereple...@gmail.comwrote:
while(arr[i] != '\0')
arr[i++] = arr[j--];
}
Think through what is happening here. What you need to do is to swap
characters in the string.
here is the solution from "Richard Heithfield":

for(i = 0; i < j; i++)
{
ch = s[i];
s[i] = s[j];
s[j] = ch;
--j;
}

this WHOLE solution relies on the *trick*:

i < j
i can never think such kind of tricks. i understand it after i worked
on a piece of paper with a simple example "like" BUT my mind or my
kind of brain can NEVER give birth to such kind of ideas, this trick
is exactly same like "how to take out money from someone's pocket OR
how to turn/bend one's life for OUR very OWN benefit". i am not
saying that programmers are selfish. i am saying that there is some
kind of correlation between these 2 *skills*, both need a difficult
and to me an alien kind of mental-exercise.

is this *trick* is what you call programming ? ?

if YES, then i think i need to change my field.

Apr 6 '07 #11

"arnuld" <ge*********@gmail.comwrote in message
news:11**********************@w1g2000hsg.googlegro ups.com...
>On Apr 6, 6:37 pm, "Jonas" <spamhereple...@gmail.comwrote:
>while(arr[i] != '\0')
arr[i++] = arr[j--];
}
>Think through what is happening here. What you need to do is to swap
characters in the string.

here is the solution from "Richard Heithfield":

for(i = 0; i < j; i++)
{
ch = s[i];
s[i] = s[j];
s[j] = ch;
--j;
}
There is more than one solution to a problem; the above could e.g. have been
solved with one index variable too:

for (i = 0; i < n / 2; i++) {
ch = s[i];
s[i] = s[n - 1 - i];
s[n - 1 - i] = ch;
}

this WHOLE solution relies on the *trick*:

i < j
i can never think such kind of tricks. i understand it after i worked
on a piece of paper with a simple example "like" BUT my mind or my
kind of brain can NEVER give birth to such kind of ideas, this trick
is exactly same like "how to take out money from someone's pocket OR
how to turn/bend one's life for OUR very OWN benefit". i am not
saying that programmers are selfish. i am saying that there is some
kind of correlation between these 2 *skills*, both need a difficult
and to me an alien kind of mental-exercise.

is this *trick* is what you call programming ? ?

if YES, then i think i need to change my field.
Practice makes perfect, it's as simple as that. The more "tricks" you have
seen and learnt, the easier it is to come up with them on your own. They are
not tricks so much as techniques, and though you might come up with some on
your own, many of them you will learn from others. So don't give up just
yet. Try to look back every now and then instead, to see how much you've
actually learnt!

--
Jonas
Apr 6 '07 #12
arnuld said:
here is the solution from "Richard Heithfield":

for(i = 0; i < j; i++)
{
ch = s[i];
s[i] = s[j];
s[j] = ch;
--j;
}

this WHOLE solution relies on the *trick*:

i < j
No, it's not a trick. It's just one approach to the problem of reversing
the characters of a string.

Basically, it works like this:

Start at BOTH ends of the string
Pick up a character from the left, and a character from the right
Swap them over
Move nearer to the middle of the string
Go round again, but stop when you get to the middle
i can never think such kind of tricks.
That's why we have whole books packed full of algorithms (which is the
fancy name we normally use for "tricks") - partly to give you a
treasurehouse of tricks which you can dip into, and partly to make you
so familiar with them that you begin to see how to put them together
yourself.
is this *trick* is what you call programming ? ?
Yes.
if YES, then i think i need to change my field.
Either that, or your attitude.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Apr 6 '07 #13
On Apr 6, 7:23 am, "arnuld" <geek.arn...@gmail.comwrote:
On Apr 6, 6:37 pm, "Jonas" <spamhereple...@gmail.comwrote:
while(arr[i] != '\0')
arr[i++] = arr[j--];
}
Think through what is happening here. What you need to do is to swap
characters in the string.

here is the solution from "Richard Heithfield":

for(i = 0; i < j; i++)
{
ch = s[i];
s[i] = s[j];
s[j] = ch;
--j;
}

this WHOLE solution relies on the *trick*:

i < j

i can never think such kind of tricks.
After you program for a little while such things are as easy as
putting on your socks in the morning.
You also do not have to solve it in exactly that way. You can come up
with any equivalent solution.
i understand it after i worked
on a piece of paper with a simple example "like" BUT my mind or my
kind of brain can NEVER give birth to such kind of ideas, this trick
is exactly same like "how to take out money from someone's pocket OR
how to turn/bend one's life for OUR very OWN benefit".
Then come up with your own idea.
i am not
saying that programmers are selfish. i am saying that there is some
kind of correlation between these 2 *skills*, both need a difficult
and to me an alien kind of mental-exercise.

is this *trick* is what you call programming ? ?
Yes.
if YES, then i think i need to change my field.
The name of the trick is "clear thinking"
Just think clearly about how you would solve the problem.

/*
* Various methods to reverse a string, cobbled from ancient clc posts.
* I have tweaked them a bit, so you might have trouble locating the
originals.
*/
#include <string.h>
#include <stdlib.h>

/* The super-cheesy xor hack: */
char *reverse0(char *s)
{
char *p1,
*p2;

if (!s || !*s)
return s;
for (p1 = s, p2 = s + strlen(s) - 1; p2 p1; ++p1, --p2) {
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return s;
}

/* The most self-evident way, I think: */
char *reverse1(char *s)
{
char *start,
*end,
tmp;
size_t length;

if (!s || !*s)
return s;
end = s + (length = strlen(start = s)) - 1;
length >>= 1;

while (length--) {
tmp = *s;
*s++ = *end;
*end-- = tmp;
}
return (start);
}

/* Using the address to know when you're done: */
char *reverse2(char *s)
{
char *beg = s;
char *end = s;
char c;

if (!s || !*s)
return s;
while (*s++) {;
}
s -= 2;
while (end < s) {
c = *end;
*end++ = *s;
*s-- = c;
}
return (beg);

}

/* Array notation instead of pointer notation (using index instead of
address): */
char *reverse3(char *s)
{
size_t i,
j;
char c;
if (!s || !*s)
return s;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
return s;

}

/* using a helper function and recursion: */
void swapstring(char *a, char *b)
{
char c;
if (a < b) {
c = *a;
*a = *b;
*b = c;
swapstring(a + 1, b - 1);
}
}

char *reverse4(char *s)
{

if (!s || !*s)
return s;
swapstring(s, s + strlen(s) - 1);
return s;
}

#ifdef UNIT_TEST
typedef char *(*rf) (char *);
rf f_list[] = {reverse0, reverse1, reverse2, reverse3,
reverse4, NULL};

char string0[] = "AB"; /* Even number of characters
*/
char string1[] = "ABC"; /* odd number of characters */
char string2[] = ""; /* zero number of characters */
char string3[] = "I am a foo bird, but I can't fly.";
char string4[] = "a man a plan a canal panama";
char *s_list[] = {
string0, string1, string2, string3, string4, NULL
};

char rs_holder[100];

int main(void)
{
size_t f_ind;
size_t s_ind;
for (f_ind = 0; f_list[f_ind]; f_ind++)
for (s_ind = 0; s_list[s_ind]; s_ind++) {
strcpy(rs_holder, s_list[s_ind]);
printf("(%s) <-(%s)\n", s_list[s_ind], f_list[f_ind]
(rs_holder));
}
return 0;
}
/*
(AB) <-(BA)
(ABC) <-(CBA)
() <-()
(I am a foo bird, but I can't fly.) <-(.ylf t'nac I tub ,drib oof a
ma I)
(a man a plan a canal panama) <-(amanap lanac a nalp a nam a)
(AB) <-(BA)
(ABC) <-(CBA)
() <-()
(I am a foo bird, but I can't fly.) <-(.ylf t'nac I tub ,drib oof a
ma I)
(a man a plan a canal panama) <-(amanap lanac a nalp a nam a)
(AB) <-(BA)
(ABC) <-(CBA)
() <-()
(I am a foo bird, but I can't fly.) <-(.ylf t'nac I tub ,drib oof a
ma I)
(a man a plan a canal panama) <-(amanap lanac a nalp a nam a)
(AB) <-(BA)
(ABC) <-(CBA)
() <-()
(I am a foo bird, but I can't fly.) <-(.ylf t'nac I tub ,drib oof a
ma I)
(a man a plan a canal panama) <-(amanap lanac a nalp a nam a)
(AB) <-(BA)
(ABC) <-(CBA)
() <-()
(I am a foo bird, but I can't fly.) <-(.ylf t'nac I tub ,drib oof a
ma I)
(a man a plan a canal panama) <-(amanap lanac a nalp a nam a)
*/
#endif

Apr 7 '07 #14
On 5 Apr 2007 22:46:38 -0700, "arnuld" <ge*********@gmail.comwrote:
>i have changed it a little bit now it doe snot print any "unprintable
characters" but it also does not print *anything*:

------------ PROGRAMME ------------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];
Why -1? If you want an array of 999, define MAXLENGTH as 999. This
is such a bad idea that it confused you later into invoking undefined
behavior.
>
for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = 0;
while(getline(arr))
{
reverse(arr);
printf("\n ****** \n%s\n", arr);
}
return 0;

}
int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; 9 < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
+i)
What are the odds that 9 < MAXLENGTH-1 will ever be false? Did you
mean i instead of 9?
arr[i] = c;

if(c == '\n')
arr[i++] = c;
Why would you want to add a \n to your string?
>
arr[i] = '\0';
You need to fix the loop so it never accepts more than 998 input
characters or this statement will attempt to write beyond the end of
the array..
>
return i;
}
void reverse(char arr[])
{
int i = 0;
int j = MAXLENGTH - 1;
char rev_arr[MAXLENGTH - 1];
Both arr and rev_arr are arrays of MAXLENGTH-1. That means the index
runs from 0 to MAXLENGTH-2.
>
for(i=0; i < j; ++i)
rev_arr[i] = 0;

while(j-- != '\0')
Surely you didn't intend to unconditionally decrement j to -1. Did
you perhaps mean arr[j--]? If so, you would invoke undefined behavior
on the first iteration since j exceeds the max allowable index for
arr.
;

while(j >= 0)
rev_arr[i++] = arr[j--];
You are aware that i no longer equals 0 at this point but in fact is
set to MAXLENGTH-1 by the preceding for loop. rev_arr[i] does not
exist. This would invoke undefined behavior except ...

j is equal to -1 courtesy of the preceding while loop. The while
evaluates to false and the loop is never executed so ....
>

for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = rev_arr[i];
All the rev_arr[i] are still 0.

Remove del for email
Apr 7 '07 #15
"arnuld" wrote
>"Jonas" wrote:
>while(arr[i] != '\0')
arr[i++] = arr[j--];
}
>Think through what is happening here. What you need to do is to swap
characters in the string.

here is the solution from "Richard Heithfield":

for(i = 0; i < j; i++)
{
ch = s[i];
s[i] = s[j];
s[j] = ch;
--j;
}

this WHOLE solution relies on the *trick*:

i < j
i can never think such kind of tricks. i understand it after i worked
on a piece of paper with a simple example "like" BUT my mind or my
kind of brain can NEVER give birth to such kind of ideas, this trick
is exactly same like "how to take out money from someone's pocket OR
how to turn/bend one's life for OUR very OWN benefit".
That's a terrible way to look at this. It's more of a
fundamental insight into the nature of the problem.

So it clarifies, not obfuscates things.

As a word of encouragement, while there may be an
infinite number of problems, they tend to fall into groups
so a surprisingly small number of techniques can be used
over and over again.

It is true that the ability to discover these things on your own
is a sign of natural programming ability, but reading a few
good book on algorithms can lead to competence.

--
Craig Franck
cr**********@verizon.net
Cortland, NY
Apr 7 '07 #16
Groovy hepcat arnuld was jivin' on 5 Apr 2007 22:46:38 -0700 in
comp.lang.c.
Re: K&R2, exercise 1-19's a cool scene! Dig it!
>i have changed it a little bit now it doe snot print any "unprintable
characters" but it also does not print *anything*:

------------ PROGRAMME ------------
/* K&R2: 1.9 Arrays, exercise 1-19

STATEMENT:
write a function reverse(s) that reverses the character string s.
use it to write a programme that revereses its input a line at a time.

*/

#include<stdio.h>

#define MAXLENGTH 1000

int getline(char arr[]);
void reverse(char arr[]);

int main(void)
{
int i = 0;
char arr[MAXLENGTH - 1];
Why MAXLENGTH - 1? Why are you subtracting 1 all the time? It
defeats the purpose of having a macro, somewhat. If you want an array
of 1000 chars, then do this:

#define MAXLENGTH 1000
....
char arr[MAXLENGTH];

Otherwise, if you want an array of 999 chars, do this:

#define MAXLENGTH 999
....
char arr[MAXLENGTH];
for(i = 0; i < MAXLENGTH - 1; ++i)
And here you want MAXLENGTH. The loop will then go from 0 to
MAXLENGTH - 1, which is what you want. But...
arr[i] = 0;
...why are you doing this at all? You don't need to clear out the
array.
while(getline(arr))
{
reverse(arr);
printf("\n ****** \n%s\n", arr);
}
return 0;

}
int getline(char arr[])
{
int c = 0;
int i = 0;

for(i=0; 9 < MAXLENGTH - 1 && (c = getchar()) != EOF && c != '\n'; +
^
Here you have 9 < MAXLENGTH - 1. Presumably you meant i < MAXLENGTH
- 1. Here, unlike above, you do need the -1. This is because the last
character in the array must be '\0'. You can, therefore, store up to
MAXLENGTH - 1 characters before the '\0'.
>+i)
arr[i] = c;

if(c == '\n')
arr[i++] = c;
Here you may have a problem. What if you've read MAXLENGTH - 1
characters? Here you store another character ('\n') in the last
element of the array, then increment the index (i). When you then
attempt to store '\0', you're trying to put it in the byte following
the end of the array. There's a better way. There are a number of
better ways. One is to simply ignore the '\n'. Another is to restrict
the number of other characters read to MAXLENGTH - 2. But that's not
what I'd do. I'd write the getline() function a little differently.
See below.
arr[i] = '\0';

return i;
}
Here's my version of getline().

#include <stdio.h>

int getline(char *s)
{
int i, c;

i = 0;
while(i < MAXLENGTH - 1 &&
EOF != (c = getchar()) &&
'\n' != (s[i++] = c))
;

s[i] = '\0';

return i;
}
>void reverse(char arr[])
{
int i = 0;
int j = MAXLENGTH - 1;
char rev_arr[MAXLENGTH - 1];
And again, you just need MAXLENGTH, not MAXLENGTH - 1.
for(i=0; i < j; ++i)
rev_arr[i] = 0;
Unnecessary. You don't need to clear out the array.
while(j-- != '\0')
;
Here you are comparing j to '\0'. Of course, '\0' is equivalent to
0, so this is legal and meaningful. The net result of this is that j
ends up with a value of -1. However, that isn't what you want. You
want to compare arr[j] to '\0', no doubt. So I assume what you were
trying to do was this:

while(arr[j--] != 0)
;
while(j >= 0)
rev_arr[i++] = arr[j--];
And since you've used i above in the loop to clear out rev_arr, i
now contains the value MAXLENGTH - 1 upon entry to this loop. You are
then attempting to store bytes from rev_arr[MAXLENGTH - 1] onward.
for(i = 0; i < MAXLENGTH - 1; ++i)
arr[i] = rev_arr[i];
}
You might try reversing the string inline. It's quite simple. You
need two pointers: one called first, which you set to the start of the
string, and the other called last, which you set to start +
strlen(start) - 1. Then while last first, you swap the character at
*first with the character at *last, then increment first and decrement
last. All very simple!

#include <string.h>

void reverse(char *s)
{
char tmp;
char *first = s;
char *last = s + strlen(s) - 1;

while(last first)
{
tmp = *first;
*first = *last;
*last = tmp;

first++;
last--;
}
}

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Apr 8 '07 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2139
by: Chris Readle | last post by:
Ok, I've just recently finished a beginning C class and now I'm working through K&R2 (alongside the C99 standard) to *really* learn C. So anyway, I'm working on an exercise in chapter one which...
16
2249
by: Josh Zenker | last post by:
This is my attempt at exercise 1-10 in K&R2. The code looks sloppy to me. Is there a more elegant way to do this? #include <stdio.h> /* copies input to output, printing */ /* series of...
4
1550
by: arnuld | last post by:
as i said, i have restarted the book because i overlooked some material. i want to have some comments/views on this solution. it runs fine, BTW. ------------------ PROGRAMME -------------- /*...
16
1779
by: arnuld | last post by:
i have created solution which compiles and runs without any error/ warning but it does not work. i am not able to understand why. i thought it is good to post my code here for correction before...
19
2373
by: arnuld | last post by:
this programme runs without any error but it does not do what i want it to do: ------------- PROGRAMME -------------- /* K&R2, section 1.6 Arrays; Exercise 1-13. STATEMENT: Write a program...
5
2901
by: arnuld | last post by:
this is a programme that counts the "lengths" of each word and then prints that many of stars(*) on the output . it is a modified form of K&R2 exercise 1-13. the programme runs without any...
2
1653
by: arnuld | last post by:
i was not even able to understand how should i proceed tow rite solution for this exercise: "Write a program to print a histogram of the frequencies of different characters in its input." ...
4
1827
by: arnuld | last post by:
any suggestions for improvement: -------------- PROGRAMME ------------- /* K&R2: section 1.5.3 exercise 1-10 STATEMENT: write a programme to copy its input to output, replacing each TAB by...
88
3664
by: santosh | last post by:
Hello all, In K&R2 one exercise asks the reader to compute and print the limits for the basic integer types. This is trivial for unsigned types. But is it possible for signed types without...
82
2746
by: arnuld | last post by:
PURPOSE :: see statement in comments GOT: Segmentation Fault I guess the segfault is sourced in the compile-time warning but I am giving a char* to the function already.
0
7153
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
7371
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,...
1
7093
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7517
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
5676
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
3230
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3218
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1583
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
791
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.