View Full Version : I wrote it
EscapeCharacter
10-10-2002, 11:03 AM
You improve it
#include <stdio.h>
char *reverse(char *);
unsigned int strlength(const char *);
int main(int argc, char **argv){
char *tmp, *tmp2;
if(argc != 2){
printf("usage: reverse string\n");
exit(0);
}
tmp = argv[1];
tmp2;
tmp2 = reverse(tmp);
printf("%s reversed = %s", tmp, tmp2);
return 0;
}
char *reverse(char *in){
char *tmp;
int i = strlength(in);
const num = i;
tmp = (char*)malloc(sizeof(char)*i);
while(i > 0){
tmp[num-i] = in[i-1];
i--;
}
printf("tmp = %s\n", tmp);
return tmp;
}
unsigned int strlength(const char *in){
unsigned int i = 0;
while(*(in+i) != '\0'){
i++;
}
return i;
}
p.s. inkedmn i finally got in the mood :)
Strike
10-10-2002, 11:36 AM
#include <stdio.h>
char *reverse(char *);
unsigned int strlength(const char *);
int main(int argc, char **argv){
char *tmp, *tmp2;
More descriptive variable names would be good. Not to mention you really don't need either of these :)
if(argc != 2){
printf("usage: reverse string\n");
exit(0);
}
Could use perror here, or sprintf and stderr.
tmp = argv[1];
tmp2;
No clue what the second line is for, get rid of it.
tmp2 = reverse(tmp);
printf("%s reversed = %s", tmp, tmp2);
return 0;
}
char *reverse(char *in){
char *tmp;
int i = strlength(in);
You mean unsigned int, consistency is good.
const num = i;
This shouldn't even parse (don't have a compiler handy to check), should be an unsigned int as well.
tmp = (char*)malloc(sizeof(char)*i);
Always check for null pointer returns from malloc, always.
while(i > 0){
tmp[num-i] = in[i-1];
i--;
}
printf("tmp = %s\n", tmp);
Should wrap this in a debugging statement somehow (using either preprocessor stuff or otherwise), as it is inessential to the function itself.
return tmp;
}
unsigned int strlength(const char *in){
unsigned int i = 0;
while(*(in+i) != '\0'){
Check and make sure in isn't a null pointer before trying to dereference it.
i++;
}
return i;
}
EscapeCharacter
10-10-2002, 11:55 AM
thats strange i forgot to include stdlib.h and it still didnt complain about malloc until i added -Wall to the command line
Bradmont
10-10-2002, 12:45 PM
you're also malloc'ing without free'ing. bad Bad BAD boy!
sans-hubris
10-10-2002, 02:39 PM
Besides, C already provides strlen() for you. Why rewrite the function?
Also, you should start using calloc() instead of malloc(), that is if you don't mind a few extra CPU cycles being used. calloc() zeroes out the memory you want before you use it.
EscapeCharacter
10-10-2002, 02:41 PM
Originally posted by sans-hubris
Besides, C already provides strlen() for you. Why rewrite the function?
just wanted to see if i could do it correctly
Dru Lee Parsec
10-10-2002, 03:07 PM
Here's how I'd improve it:
public class ReverseString {
public static void main(String[] args) {
if ((args.length == 0) || (args.length > 1)) {
System.out.println("Usage: java ReverseString <a string>");
} else {
StringBuffer buffer = new StringBuffer(args[0]);
System.out.println(buffer.reverse());
}
}
}
OK, OK, I admit it. That was a troll. ;) Posting Java code on a C++ thread is asking for trouble.
I guess I'm just feeling bored at work and I want a beer.
Strike
10-10-2002, 03:07 PM
stdlib.h is implicitly included no matter what. The only way to not include it is by passing the --nostdinc flag to the compiler (I believe that's the one).
EscapeCharacter
10-10-2002, 03:20 PM
ah i see, thanks for pointing that out didnt know some headers were automatically included. and as for Dru go back to your java world :P
Strike
10-10-2002, 03:57 PM
Originally posted by Dru Lee Parsec
Here's how I'd improve it:
public class ReverseString {
public static void main(String[] args) {
if ((args.length == 0) || (args.length > 1)) {
System.out.println("Usage: java ReverseString <a string>");
} else {
StringBuffer buffer = new StringBuffer(args[0]);
System.out.println(buffer.reverse());
}
}
}
OK, OK, I admit it. That was a troll. ;) Posting Java code on a C++ thread is asking for trouble.
I guess I'm just feeling bored at work and I want a beer.
Yeah, I almost did the same thing in Python ... ah hell, here it is:
import sys
if len(sys.argv != 2):
print "Syntax: reverse.py <string>"
sys.exit(0)
else:
print sys.argv[1].reverse()
(untested)
jamessan
10-10-2002, 04:48 PM
int main(int argc, char **argv)
{
if(argc != 2)
{
fprintf(stderr,"usage: reverse string\n");
exit(1);
}
int len=strlen(argv[1]);
for(argv[1]+=(len-1)*sizeof(char);len>0;len--,argv[1]-=sizeof(char))
printf("%c",*argv[1]);
return 0;
}
sans-hubris
10-10-2002, 05:23 PM
Originally posted by Dru Lee Parsec
Here's how I'd improve it:
public class ReverseString {
public static void main(String[] args) {
if ((args.length == 0) || (args.length > 1)) {
System.out.println("Usage: java ReverseString <a string>");
} else {
StringBuffer buffer = new StringBuffer(args[0]);
System.out.println(buffer.reverse());
}
}
}
OK, OK, I admit it. That was a troll. ;) Posting Java code on a C++ thread is asking for trouble.
I guess I'm just feeling bored at work and I want a beer. See, but his code isn't really C++, it's really just pure C. You want C++?
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
int main(int argc, char ** argv)
{
if(argc!=2) {
cout << "usage: " << argv[0] << " <string>" << endl;
exit(1);
}
reverse(argv[1], &argv[1][strlen(argv[1])]);
cout << argv[1] << endl;
return 0;
}
EscapeCharacter
10-10-2002, 06:00 PM
ok wheres the assembly example :P
sedarious
10-11-2002, 03:04 PM
Originally posted by EscapeCharacter
ok wheres the assembly example :P
Tonight perhaps.
Originally posted by Strike
stdlib.h is implicitly included no matter what. The only way to not include it is by passing the --nostdinc flag to the compiler (I believe that's the one).
I don't think that's right.
-nostdinc
Do not search the standard system directories for
header files. Only the directories you have speci-
fied with `-I' options (and the current directory,
if appropriate) are searched.
By using both `-nostdinc' and `-I-', you can limit
the include-file search file to only those directo-
ries you specify explicitly.
I think the real reason it works is that undefined functions are implicitly defined to return int and take whatever kind of args you pass them, and malloc returns an int (and the code is casting it anyway). When you compile with -Wall it'll tell you that it's being implicitly defined.
The linker links with stdlib by default though, unless you provide the -nostdlib switch. I think that's what you were thinking of. (and part of why it works)
Unless I'm totally wrong.. :P
Strike
10-14-2002, 12:41 PM
nex: I think the -nostdlib flag is probably what I was thinking of, thanks.
sedarious
10-15-2002, 04:14 PM
Sorry it took so long - had some issues finding correct documentation on command line parameters for windows...
org 0x100 ;set our offset
xor bh,bh ;zero high byte of bx
mov bl,[es:0x80] ;move the length of the argument string to bl
mov ah,2h ;setup ax - 0x02 is for single character display
loopage: ;our label
mov dl,[es:bx+0x80] ;move character to dl
dec bl ;decrement bl (where we are looking)
int 21h ;call DOS interrupt to display dl in move the cursor
cmp bl,0x00 ;check to see if bl is zero
jne loopage ;goto start of loop if not
mov ah,4ch ;setup ax - 0x4c is terminate program call
int 21h ;call DOS interrupt to terminate program
edit: BTW, this will only work in DOS 5.0 and above because of the command line argument procedure.
phubuh
10-16-2002, 04:14 AM
>+[>,][<.]
sans-hubris
10-16-2002, 06:57 AM
Originally posted by phubuh
>+[>,][<.]
Ah, the BF (http://www.muppetlabs.com/~breadbox/bf/) version, the best one! Not to mention the shortest.
skidooer
11-05-2002, 08:54 PM
My reverse does not suffer from your memory leaks.
char * reverse(char *in)
{
int len = strlen(in);
int pos, lpos;
for(pos = 0; pos < len / 2; pos++)
{
lpos = len - pos - 1;
in[pos] ^= in[lpos];
in[lpos] ^= in[pos];
in[pos] ^= in[lpos];
}
return in;
}
And my alternate strlength (of course this is a standard function, why reinvent the wheel?):
unsigned int strlength(char *str)
{
char *ptr = str;
while(*ptr++);
return ptr - str - 1;
}
DrPizza
11-18-2002, 10:17 AM
The brainfuck version is quite pleasing -- unusual for a brainfuck program to both short and easy to read, but it manages it.
I think it's the only BF program I've seen that /does/ manage such a feat, mind you.
jemfinch
11-18-2002, 05:16 PM
Originally posted by Strike
unsigned int strlength(const char *in){
unsigned int i = 0;
while(*(in+i) != '\0'){
Check and make sure in isn't a null pointer before trying to dereference it.
That should be done outside of strlength; strlength itself should assume that the checking has already been done. It's the caller's responsibility to check arguments, not the callee's.
import sys
if len(sys.argv != 2):
print "Syntax: reverse.py <string>"
sys.exit(0)
else:
print sys.argv[1].reverse()
Strings have no .reverse method in Python.
aList = list(sys.argv[1])
aList.reverse()
print ''.join(aList)
That's what you need to do to reverse a string in Python. And it's horribly inefficient.
Originally posted by skidooer:
My reverse does not suffer from your memory leaks.
char * reverse(char *in)
{
int len = strlen(in);
int pos, lpos;
for(pos = 0; pos < len / 2; pos++)
{
lpos = len - pos - 1;
in[pos] ^= in[lpos];
in[lpos] ^= in[pos];
in[pos] ^= in[lpos];
}
return in;
}
Your reverse modifies its arguments in place, and thus should return void, not a char *. Returning a char* is misleading because it leads the caller to believe he's getting a new return value, instead of modifying his original value.
And be careful with your little XOR-trick. If you try to do it on overlapping memory locations you'll really mess things up.
Jeremy
DrPizza
11-19-2002, 04:23 AM
That should be done outside of strlength; strlength itself should assume that the checking has already been done. It's the caller's responsibility to check arguments, not the callee's.
Except of course when it isn't. C is inconsistent on the matter; some functions assume good parameters, others will return errors if their parameters are invalid. To announce the existance of some "rule" as you have done here is to somewhat ignore reality.
jemfinch
11-19-2002, 10:35 AM
Originally posted by DrPizza
Except of course when it isn't. C is inconsistent on the matter; some functions assume good parameters, others will return errors if their parameters are invalid. To announce the existance of some "rule" as you have done here is to somewhat ignore reality.
Feel free to offer some examples of where it isn't the rule. I would argue that those are examples of someone "somewhat ignoring reality."
Jeremy
DrPizza
11-19-2002, 01:47 PM
strtoXxx() and wsctoXxx() will set errno to ERANGE if the value is outside the range of their destination number type.
The multibyte <-> wide char conversion functions will set errno to EILSEQ if an illegal encoding is encountered.
Various floating point routines may set (but are not required to set) errno to indicate domain errors or certain other conditions.
These things can all be checked prior to calling the function, but in fact are checked within the function itself. There are probably others; those are the ones I know off hand.
DrPizza
11-19-2002, 06:27 PM
Your reverse modifies its arguments in place, and thus should return void, not a char *. Returning a char* is misleading because it leads the caller to believe he's getting a new return value, instead of modifying his original value.
In the same way that memcpy(), memmove(), strcpy(), strncpy(), strcat(), strncat(), strtok(), and memset() are "misleading" for the same reason?
There is established precedent for such routines to return pointers to the string passed in. It is not misleading -- it is the Standard behaviour.
vBulletin® v3.7.0, Copyright ©2000-2009, Jelsoft Enterprises Ltd.