#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    22
    Rep Power
    0

    Character Scrambler.


    Hello once again. I am facing a few problems with my character scrambler. So I have one function which takes as input one array of characters and scrambles the word. For example if I give "Test" it should return me something like "esTt". I manage to compile it but when I run it, it crashes. Here's the code.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <String.h>
    char* reverse(char a[])
    {
           char* b; // array to return with the scrambled word
           b=(char*)malloc(10*sizeof(char));
           int i;
           char swap;  //char to swap;
        for(i=0;i<strlen(a);i++)
        {
                    int index=rand() % (strlen(a)-1-i); //Generates a random number which will determine which character will be picked. 
                    b[i]=a[index]; //The character which got picked is saved in b array
                    swap=a[index]; //Now I swap the characterwhich got picked with the last element of the array so I wont be able to pick it twice.
                   a[index]=a[(strlen(a)-1-i)];
                    a[(strlen(a)-1-i)]=swap;
                    
        }
        b[i+1]='\0'; //Termination of the string;
        
        return b;
    }
    int main()
    {
        char c[10];
        char *d;
        c[1]='T';
        c[2]='E';
        c[3]='S';
        c[4]='T';
        c[5]='\0';
      d=reverse(c);
      printf("%s",d);
      free(d);
        system("pause");
    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Your primary problem is that you tried to run a program that is clearly broken as indicated by all the warnings that the compiler throws because of it. Never ignore warnings!

    Using MinGW gcc on Win7-64:
    C:\otros\dcw>gcc -Wall uniflame2.c
    uniflame2.c: In function `reverse':
    uniflame2.c:8: parse error before `int'
    uniflame2.c:10: `i' undeclared (first use in this function)
    uniflame2.c:10: (Each undeclared identifier is reported only once
    uniflame2.c:10: for each function it appears in.)
    uniflame2.c:14: `swap' undeclared (first use in this function)
    uniflame2.c: In function `main':
    uniflame2.c:36: warning: control reaches end of non-void function

    C:\otros\dcw>
    Since you are apparently doing this in C99, then how the hell do you expect us to be able to help you?

    Why do you use the first character of c without ever setting it to a known value?
    Code:
        char c[10];
        char *d;
        c[1]='T';
        c[2]='E';
        c[3]='S';
        c[4]='T';
        c[5]='\0';
      d=reverse(c);
    Where do you ever set c[0]?

    SUGGESTION: Do you ever expect strlen(a) to change? I wouldn't. So why not declare a length variable that you set to strlen(a) and then use that variable? It would save you from making all those unnecessary function calls.

    And what happens if strlen(a) is zero? Since zero is one of the possible garbage values that a[0] could just happen to be, you need to account for that. Your for-loop would not execute, but since b[0] is also not initialized and contains garbage, you would have no idea what it could be set to.

    So much garbage, so little time.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    22
    Rep Power
    0
    Originally Posted by dwise1_aol
    Your primary problem is that you tried to run a program that is clearly broken as indicated by all the warnings that the compiler throws because of it. Never ignore warnings!

    Using MinGW gcc on Win7-64:

    Since you are apparently doing this in C99, then how the hell do you expect us to be able to help you?

    Why do you use the first character of c without ever setting it to a known value?
    Code:
        char c[10];
        char *d;
        c[1]='T';
        c[2]='E';
        c[3]='S';
        c[4]='T';
        c[5]='\0';
      d=reverse(c);
    Where do you ever set c[0]?

    SUGGESTION: Do you ever expect strlen(a) to change? I wouldn't. So why not declare a length variable that you set to strlen(a) and then use that variable? It would save you from making all those unnecessary function calls.

    And what happens if strlen(a) is zero? Since zero is one of the possible garbage values that a[0] could just happen to be, you need to account for that. Your for-loop would not execute, but since b[0] is also not initialized and contains garbage, you would have no idea what it could be set to.

    So much garbage, so little time.
    CHECK THE CODE IN THE BELOW POST.

    I stopped using strlen function so much and I fixed the c[0] value. Now the only problem I have is that it always returns the following words "SET".
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    22
    Rep Power
    0
    UPDATE:

    I fixed some more issues with my code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <String.h>
    char* reverse(char a[])
    {
           char* b; // array to return with the scrambled word
           b=(char*)malloc(10*sizeof(char));
           b[0]='a';
           int i=0;
           char swap='a';  //char to swap;
           int counter=strlen(a);
           printf("%d \t",counter);
        for(i=0;i<counter;i++)
        {
                    
                    int index=rand() % (counter-i); //Generates a random number which will determine which character will be picked. 
                    printf("%d \t",index);
                    b[i]=a[index]; //The character which got picked is saved in b array
                    swap=a[index]; //Now I swap the characterwhich got picked with the last element of the array so I wont be able to pick it twice.
                   a[index]=a[(counter-i)];
                    a[counter-i]=swap;
                    
        }
        b[4]='\0'; //Termination of the string;
        
        return b;
    }
    int main()
    {
        char c[10]={'\0'};
        char *d;
        c[0]='O';
        c[1]='K';
        c[2]='A';
        c[3]='Y';
        c[4]='\0';
      d=reverse(c);
      printf("%s \t",d);
      free(d);
        system("pause");
    }
    Now it works properly but it still throws me the same letter combination all the time. KAOY. Is it because of the rand() function?
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    You need to set the random seed. rand is a pseudo-random number generator that uses deterministic calculations. If it starts with the same initial value (the "seed"), then it will produce the same "random" sequence of values.

    The srand() function sets the seed. If you had read the documentation for rand (eg, its man page), then you would have read about srand. Call srand once as one of the first things you do in main and you would be set up. One common practice that is guaranteed to give srand a unique value each time is to feed it the return value of time() (read the man page for time() for specifics).

    BTW, you would want to set the end of the string in b to '\0' regardless of the length of the string. For any length string, the index of the null-terminator is equal to strlen(string).
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    22
    Rep Power
    0
    I updated the code by using the srand function. Now the problem is that when I run it the word "OKAY" sometimes doesnt come full. I mean that one or more letters are 'lost'.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <String.h>
    #include <Time.h>
    char* reverse(char a[])
    {
           char* b; // array to return with the scrambled word
           b=(char*)malloc(10*sizeof(char));
           b[0]='a';
           int i=0;
           char swap='a';  //char to swap;
           int counter=strlen(a);
           printf("%d \t",counter);
        for(i=0;i<counter;i++)
        {
                    
                    int index=rand() % (counter-i); //Generates a random number which will determine which character will be picked. 
                    printf("%d \t",index);
                    b[i]=a[index]; //The character which got picked is saved in b array
                    swap=a[index]; //Now I swap the characterwhich got picked with the last element of the array so I wont be able to pick it twice.
                   a[index]=a[(counter-i)];
                    a[counter-i]=swap;
                    
        }
        b[4]='\0'; //Termination of the string;
        
        return b;
    }
    int main()
    {
        //time_t rawtime;
        srand(time(NULL));
        char c[10]={'\0'};
        char *d;
        c[0]='O';
        c[1]='K';
        c[2]='A';
        c[3]='Y';
        c[4]='\0';
      d=reverse(c);
      printf("%s \t",d);
      free(d);
        system("pause");
    }
    EDIT: I actually figured it out. I forgot to add -1 at lines 21 and 22. It works perfectly now. Thanks for the help. This can be locked.

IMN logo majestic logo threadwatch logo seochat tools logo