Thread: Please help! Novice coder trying to figure c out.

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    10

    Please help! Novice coder trying to figure c out.

    I'm new to C and need some help figuring out this error.I've only just started coding my main function but decided to compile it to test it; I get this error.
    Undefined first referenced
    symbol in file
    simpleEncrypt lab2.o
    ld: fatal: Symbol referencing errors. No output written to a.out
    collect2: ld returned 1 exit status
    Here is my code so far:

    encrypt.h
    Code:
    /*!
     *  Replaces each letter in the character array wih its next lexicographical
     *  letter.
     *  Sample: "Good" becomes "Hppe"
    !*/
    char simpleEncrypt(char input[20]);
    
    /*!
     *  Add to each letter with its index in the given input.
     *  Sample: "Good" becomes "Gpqg"
     *
    !*/
    char mediumEncrypt(char input[20]);
    
    /*!
     *  Add to each letter with the square of its index in the given
     *  input.
     *  Sample: "Good" becomes "Gpsm"
    !*/
    char ultraEncrypt(char input[20]);

    encrypt.c
    Code:
    #include"encrypt.h"
    #include<stdio.h>
    
    char simpleEncrypt(char input[20])
    {
      int i, len = strlen(input);
      //for loop goes through all the characters in input and adds 1 to the ascii value 
      //of each character
      for(i = 0;i < len; i++)
        {
          input[i] = (int)input[i];
          input[i]++;
          //if the character is now ascii value 91 then we must loop around to ascii 
          //value 65. In other words goes from Z to A.
          if(input[i] == 91)
        {
          input[i] = 65;
        }
          //if the character is now ascii value 123 then we must loop around to ascii
          //value 97. In other words goes from z to a.
          if(input[i] == 123)
        {
          input[i] = 97;
        }
          //go back to the char value of the character being encrypted.
          input[i] = (char)input[i];
        }
      return *input;
    }
    
    char mediumEncrypt(char input[20])
    {
      int i, len = strlen(input);
    
      for(i = 0;i < len; i++)
        {
          input[i] = (int)input[i];
          input[i] = input[i] + i;
          if(input[i] >= 91)
        {
          input[i] = input[i]-26;
        }
          if(input[i] >= 123)
        {
          input[i] = input[i]-26;
        }
          input[i] = (char)input[i];
        }
      return *input;
    }
    
    char ultraEncrypt(char input[20])
    {
      int i, len = strlen(input);
    
      for(i = 0;i < len; i++)
        {
          input[i] = (int)input[i];
          int upper;
          if(input[i] >= 65 && input[i] <= 90)
        {
          upper++;
        }
          input[i] = input[i] + (i*i);
          if(upper == 1)
        {
          while(input[i] > 90)
            {
              int count;
              count = input[i] - 90;
              input[i] = 65 + count;
            }
        }
          else
        {
          while(input[i] > 122)
            {
              int count;
              count = input[i] - 122;
              input[i] = 97 + count;
            }
        }
          input[i] = (char)input[i];
        }
      return *input;
    }

    lab2.c

    Code:
    #include"encrypt.h"//make your function declaration in this .h file
    #include<stdio.h>
    //#include<encrypt.c>
    
    
    int main()
    {
      char input[20], encrypt[7], new[20];
      printf("Please enter a sentence to encrypt: ");
      scanf("%d", input);
      printf("Please enter encryption level: 's' for simple, 'm' for medium, or 'u' for ultra.");
      scanf("%d", encrypt);
      if(encrypt[0] == 's')
        {
          printf("Original word is: ");
          printf("%d\n", input);
          //new = simpleEncrypt(input);
          printf("Encrypted word is: ");
          printf("%d",simpleEncrypt(input));
        }
        //1)Request user input and also the security level
        
        //2) Use some datastructure to save the input data
        
        //3) Call the function which is defined in your encrypt.c file
        
        //4) Output the result
        
        return 1;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    You need to type in
    gcc encrypt.c lab2.c

    Once you have a few files, you will learn about makefiles, so you don't have to keep recompiling files that haven't changed.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    10
    Quote Originally Posted by Salem View Post
    You need to type in
    gcc encrypt.c lab2.c

    Once you have a few files, you will learn about makefiles, so you don't have to keep recompiling files that haven't changed.
    Ok, so to compile the whole file would I do:
    gcc -S lab2.c
    gcc -c lab2.s
    gcc encrypt.c lab2.c
    gcc lab2.o
    gcc -o lab2 lab2.o
    and then finally run it with lab2?

    Thank you so much!

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    gcc encrypt.c lab2.c -o lab2     // to compile
    ./lab2                           // to run

  5. #5
    Registered User
    Join Date
    Apr 2012
    Posts
    10
    Thanks a lot guys! I finally got it to compile so now I have a lot of debugging to do!
    What I think I'm doing when I do.
    Code:
    input[i] = (int)input[i];
          input[i]++;
    Is taking the ascii value of the character and incrementing it by one. So that an input of "Good" would turn out being "Hppe", this is not at all what I'm getting (getting:-4260928, receiving:0). Am I accessing the address of the variable and not the object it is pointing to? Also for some reason the terminal window does not prompt the user for input when I write:
    Code:
        printf("Please enter encryption level: 's' for simple, 'm' for medium, or 'u' for ultra.");
         scanf("%d", encrypt);
    Thanks again for all the help!

  6. #6
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by aleflow7 View Post
    Also for some reason the terminal window does not prompt the user for input when I write:
    Code:
        printf("Please enter encryption level: 's' for simple, 'm' for medium, or 'u' for ultra.");
         scanf("%d", encrypt);
    That is because "%d" expects an int, you pass a string ( char * ) and both encrypt and input are strings.
    use "%s" for a string

    Didn't understand the rest of your questions.
    Kurt

  7. #7
    Registered User
    Join Date
    Apr 2012
    Posts
    10
    Quote Originally Posted by ZuK View Post
    That is because "%d" expects an int, you pass a string ( char * ) and both encrypt and input are strings.
    use "%s" for a string

    Didn't understand the rest of your questions.
    Kurt
    Sorry for the weird wording, it appears my problem had to do with the way I was getting the input. But now I get a segmentation fault when I run. Could you guys help me spot where I am causing this?

    char simpleEncrypt(char input[20]) {
    int i, len = strlen(input);
    //for loop goes through all the characters in input and adds 1 to the ascii value
    //of each character
    for(i = 0;i < len; i++) {
    input[i] = (int)input[i];
    input[i]++;
    //if the character is now ascii value 91 then we must loop around to ascii
    //value 65. In other words goes from Z to A.
    if(input[i] == 91) {
    input[i] = 65;
    }
    //if the character is now ascii value 123 then we must loop around to ascii
    //value 97. In other words goes from z to a.
    if(input[i] == 123) {
    input[i] = 97;
    }
    //go back to the char value of the character being encrypted.
    input[i] = (char)input[i];
    }
    return *input;
    }
    Last edited by aleflow7; 04-29-2012 at 10:21 AM.

  8. #8
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    It crashes because you have the format string wrong again.
    Code:
          printf("%d",simpleEncrypt(input));
    "%d"expects an int but simpleEncrypt() returns a char.


    all this
    Code:
     input[i] = (char)input[i];
    don't have any effect
    what it does is take the char at position i converts it to a char (it is already a char) and stores it at position i.
    on some other place you have
    Code:
          input[i] = (int)input[i];
    this converts the char at poisition i to an int and then stores it at position i. since there is not enough space to store an int in that place the compiler converts it silently back to a char -> no effect

    Kurt
    Last edited by ZuK; 04-29-2012 at 10:50 AM.

  9. #9
    Registered User
    Join Date
    Apr 2012
    Posts
    10
    Thanks for the help again, but I can't seem to figure this out. If I am using a string (char*) and I increment a value in the string (string[0]++) am I incrementing the ASCII value for the char? Or doing something else? Even fixing all the bugs you guys have helped me out with I'm still very confused on why my program keeps performing a segmentation fault.

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    In the call to your encryption procs:

    Code:
    char simpleEncrypt(char input[20])
    You're designating a return of a single char data type, but you're returning only the first character of your parameter:

    Code:
     return *input;
    You could simply pass the array from main, receive it as a pointer, get the length (for bounds checking) and do your manipulation on that with no return value. If you pass an unsubscripted array, you pass the address of it allowing you to change the contents, so when the function returns, the changes stay.

    Segmentation faults can indicate accessing an array out of bounds or attempting to write to a NULL pointer or a pointer that has not been allocated/initialized.
    Last edited by Cynic; 04-29-2012 at 05:12 PM.

  11. #11
    Registered User
    Join Date
    Apr 2012
    Posts
    10
    So you're saying to have something like:
    Code:
    void simpleEncrypt(char input[])
    {
      int i, len = strlen(input);
      //for loop goes through all the characters in input and adds 1 to the ascii value 
      //of each character
      for(i = 0;i < len; i++)
        {
          input[i]++;
          //if the character is now ascii value 91 then we must loop around to ascii 
          //value 65. In other words goes from Z to A.
          if(input[i] == 91)
        {
          input[i] = 65;
        }
          //if the character is now ascii value 123 then we must loop around to ascii
          //value 97. In other words goes from z to a.
          else if(input[i] == 123)
        {
          input[i] = 97;
        }
        }
    }

  12. #12
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    I'd recommend receiving it as a pointer:

    Code:
    void simpleEncrypt(char *input)

  13. #13
    Registered User
    Join Date
    Apr 2012
    Posts
    10
    Ok, now I'm getting a warning: passing arg 1 of 'simpleEncrypt' makes pointer from integer without a cast. What does this mean? And when I run the program I still get a segmentation fault. I think my main mistake was to start coding without being super careful with pointers, now I'm really confused by everything. Thanks again for your patience dealing with such a bad C coder. Here's what my code looks like now:
    Code:
    void simpleEncrypt(char *input)
    {
      int i, len = strlen(input);
      //for loop goes through all the characters in input and adds 1 to the ascii value 
      //of each character
      for(i = 0;i < len; i++)
        {
          input[i]++;
          //if the character is now ascii value 91 then we must loop around to ascii 
          //value 65. In other words goes from Z to A.
          if(input[i] == 91)
        {
          input[i] = 65;
        }
          //if the character is now ascii value 123 then we must loop around to ascii
          //value 97. In other words goes from z to a.
          else if(input[i] == 123)
        {
          input[i] = 97;
        }
        }
    }

  14. #14
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    What does the call of simpleEncrypt look like? You'll need to change your prototypes.

    This:

    Code:
    /*!
     *  Replaces each letter in the character array wih its next lexicographical
     *  letter.
     *  Sample: "Good" becomes "Hppe"
    !*/
    char simpleEncrypt(char input[20]);
    Becomes this:

    Code:
    /*!
     *  Replaces each letter in the character array wih its next lexicographical
     *  letter.
     *  Sample: "Good" becomes "Hppe"
    !*/
    char simpleEncrypt(char *input);
    The same for the other functions definitions and prototypes.
    Last edited by Cynic; 04-29-2012 at 05:37 PM.

  15. #15
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    How are you calling the function? Are you using double quotes "" or a variable?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C# for a C++ coder
    By KIBO in forum C# Programming
    Replies: 5
    Last Post: 04-07-2012, 01:10 AM
  2. new coder using Dev C++
    By newcoder3333 in forum C++ Programming
    Replies: 3
    Last Post: 07-29-2006, 05:35 PM
  3. HL2 mod needs coder
    By livewire in forum Projects and Job Recruitment
    Replies: 0
    Last Post: 07-30-2005, 10:29 AM
  4. Replies: 10
    Last Post: 06-17-2005, 10:00 PM
  5. Profile of a coder
    By iain in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 08-20-2001, 06:05 AM

Tags for this Thread