Saturday, May 22, 2010

Word scrambler in C?

I'm trying to make code to scramble a word and it seems right, but everytime I call this function, the program crashes:








void scramble(char** word) // Pointer to (char* ) style string


{


......int length = strlen(*word);





......for(int i = 0; i %26lt; length; i++)


......{


............int rand1 = rand() % length;


............int rand2 = rand() % length;





............// Switch letters at rand1 and rand2


............char temp = (*word)[rand1];


............(*word)[rand1] = (*word)[rand2];


............(*word)[rand2] = temp;


......}


}

Word scrambler in C?
Good points by Steve T. above.





Your problem may be in how you're calling the function. I took your function, created main( ) as shown below, and the scramble function runs without crashing.





#include "stdio.h"


#include "stdlib.h"


#include "string.h"


#include "time.h"





#define MAX_WORD 256





void scramble(char** word);





int main(int argc, char *argv[]) {


char s[MAX_WORD];


char *word = s;


int done = 0;





srand(time(NULL));


do {


memset(s,0,MAX_WORD);


printf("\nEnter word (x to exit): ");


fgets(s,MAX_WORD,stdin);


*strchr(s,'\n') = '\0';


done = ((strlen(s) == 1) %26amp;%26amp; s[0] == 'x');


if (!done) {


printf("\n%s scrambled = ",s);


scramble(%26amp;word);


printf("%s\n",s);


}


} while (!done);





return 0;


}
Reply:What he said about the crashing, make sure your string is null-terminated.


Also, why do you need a pointer to a pointer (char**)? That seems a bit unnecessary since passing in a pointer would accomplish what you want it to (change the string you pass in and not make a copy of it).





As per your scrambling scheme it actually is suboptimal. One best way to scramble letters or anything is using the Fisher-Yates-Knuth shuffling algorithm (see sources). Essentially the problem with your shuffling scheme is that it shuffles too much in some spots and not enough in others. If you look at the source code for Fisher-Yates it will look awfully like yours but it does the shuffling in a specific order.





Also, for a more effective scrambler make sure you seed your random number (using srand). A common way to do it is to use the command "srand(time(NULL));" (you need to include time.h) though this isn't a terribly great solution. Only saying because I don't see it in your function.





Furthermore, if you are really, really concerned with randomness you might wanna look at your rand statements. When you say "rand() % length", functionally youre mapping all of the possible numbers from rand onto the numbers from [0,length-1]. However, since length doesn't divide the maximum possible rand number evenly (and since rand is a weak pseduo random number generator) your numbers will have a bias. In particular, smaller numbers would have a slightly higher chance of appearing than larger numbers. The wikipedia page discusses this as well.





http: //en . wiki pedia . org /wiki/ Fisher-Yates_shuffle





^Fill in the spaces for the above. I tried submitting this and yahoo gave an error since its from wikipedia.
Reply:The only thing that I can see that would cause your function to crash is the call to strlen(). It expects the string to be null-terminated, and will crash if it's not.





Make sure that the string you pass into this function has a null at the end.





The other thing you can do is put some printf() statements into your code at various places to see where it's crashing.


No comments:

Post a Comment