K&R2, exercise 1-19

A

arnuld

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 = 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 = c;

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

arr = '\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 = rev_arr;

}

-------------- 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]$
 
U

user923005

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 = 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 = c;

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

arr = '\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][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 = rev_arr;

}

-------------- 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]$
 
A

arnuld

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


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

what does that mean ?

[garbage][h][\0] OR [h][\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 = rev_arr;

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

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


please don't top post, it confuses me
 
A

arnuld

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 = 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 = c;

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

arr = '\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 = 0;

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

while(j >= 0)
rev_arr[i++] = arr[j--];


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

}

--------- 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]$
 
J

Jonas

arnuld said:
If you typed in 'hi' then arr will contain:
[h][0]


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

what does that mean ?

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


The latter.
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).
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'...
 
A

arnuld

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

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

what does that mean ?
[garbage][h][\0] OR [h][\0][garbage]


The latter.


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).


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 = 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 = c;

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

arr = '\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 = 0;

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

rev_arr = '\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 != '\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]$
 
J

Jonas

arnuld said:
Actually, you're not. In-place means only using additional storage of
constant size; you are using additional storage of size O(n).





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 = 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 = c;

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

arr = '\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 = 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 = arr[j];

rev_arr = '\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 != '\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[]);
 
A

arnuld

"arnuld" <[email protected]> wrote 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 = 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 ?

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

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

look much better, changed ....
rev_arr = arr[j];

rev_arr = '\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 != '\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 :)
 
J

Jonas

arnuld said:
On Apr 6, 4:51 pm, "Jonas" <[email protected]> wrote:
"arnuld" <[email protected]> wrote 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 = 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.
j = size? j is initialized correctly above. How about

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

look much better, changed ....
rev_arr = arr[j];

rev_arr = '\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 != '\0')
arr[i++] = arr[j--];
}


Think through what is happening here. What you need to do is to swap
characters in the string.
 
A

arnuld

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 != '\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.
 
A

arnuld

while(arr != '\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;
s = 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.
 
J

Jonas

arnuld said:
On Apr 6, 6:37 pm, "Jonas" <[email protected]> wrote:
while(arr != '\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;
s = 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;
s = 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!
 
R

Richard Heathfield

arnuld said:
here is the solution from "Richard Heithfield":

for(i = 0; i < j; i++)
{
ch = s;
s = 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.
 
U

user923005

while(arr != '\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;
s = 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;
s = 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
 
B

Barry Schwarz

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 = 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 = c;

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


Why would you want to add a \n to your string?
arr = '\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 = 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 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 = rev_arr;


All the rev_arr are still 0.



Remove del for email
 
C

Craig Franck

"Jonas" wrote:
while(arr != '\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;
s = 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.
 
P

Peter Shaggy Haywood

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...


...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 = 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 = '\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 = '\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 = 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 = rev_arr;
}


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"?
 

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

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top