Thread: Trouble with pointers, ascii values, and string manipulation

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    37

    Trouble with pointers, ascii values, and string manipulation

    Hi, i'm pretty new to programming (as you will see), and i'm having difficulty with this program that takes a string and adds a number (i) to each character's acsii value based on its index in the string (i). For example, the string "aaaaa" would become "abcde".

    Here's the code:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    main()
    {
    	char *origin;
    	int sLimit = strlen(origin);
    	int i;
    	
    	printf("Enter a string to encode.\n\n");
    	scanf("%s",origin);
    
    	for (i=0;i<sLimit;i++) {
    		
    		printf("Value %i: %i\n", i, origin[i]+i);
    		
    	}
    }
    The program successfully complies, but when i enter the string "aaaa", i get the following output:


    Enter a string to encode.

    aaaa
    Value 0: 97
    Value 1: 98
    Segmentation fault

    Any help would be appreciated!
    Last edited by bluej322; 01-04-2011 at 04:40 PM.

  2. #2
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Code:
    char *origin;
    Try allocating some space for your string. Then you need to move the call to strlen to a point after you have actually gotten user input into the array.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Read up on the printf documentation. You're printing the value out using the %i format, which means "treat this as an integer". Try the %c format for "treat this as a character".

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Oh, and to follow kermit's suggestion, you can't call strlen until after your scanf. There will be garbage in the string until you place something (user input) in there.

    And it's int main(void), and return 0 when you're done: http://faq.cprogramming.com/cgi-bin/...&id=1043284376

  5. #5
    Registered User
    Join Date
    Jan 2011
    Posts
    37
    Quote Originally Posted by kermit View Post
    Code:
    char *origin;
    Try allocating some space for your string. Then you need to move the call to strlen to a point after you have actually gotten user input into the array.
    Thanks! I moved the strlen() and allocated space for the string and it looks like it's working.
    Can you explain why using "origin[10]" works and "*origin" doesn't?

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    char origin[10] creates an array of 10 characters, which is sufficient to store a string of length 9, plus one byte for the trailing null character that tells C that the string is done. char *origin simply allocates space for a pointer to a character. This is meant to store a memory address and it's size depends on your system (typically 32 bits for a 32-bit system). Defining a pointer variable doesn't allocate space for it to point to. Think of it as an entry in your address book. Writing in somebody's address doesn't create a house, it just tells you where that house is.

  7. #7
    Registered User
    Join Date
    Jan 2011
    Posts
    37
    Quote Originally Posted by anduril462 View Post
    char origin[10] creates an array of 10 characters, which is sufficient to store a string of length 9, plus one byte for the trailing null character that tells C that the string is done. char *origin simply allocates space for a pointer to a character. This is meant to store a memory address and it's size depends on your system (typically 32 bits for a 32-bit system). Defining a pointer variable doesn't allocate space for it to point to. Think of it as an entry in your address book. Writing in somebody's address doesn't create a house, it just tells you where that house is.
    Okay, that makes sense. But once i use scanf to assign data to that allocation of space am i not "building the house" at that address?

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by bluej322 View Post
    Okay, that makes sense. But once i use scanf to assign data to that allocation of space am i not "building the house" at that address?
    To carry this analogy a bit too far, all scanf does is put furniture in the house. If you point it somewhere where there isn't a house, then it's just going to dump it at the side of the road. (And more the point: if the address you give it is somewhere you can't legally go, then everything's going to stop.)

  9. #9
    Registered User
    Join Date
    Jan 2011
    Posts
    37
    Quote Originally Posted by tabstop View Post
    To carry this analogy a bit too far, all scanf does is put furniture in the house. If you point it somewhere where there isn't a house, then it's just going to dump it at the side of the road. (And more the point: if the address you give it is somewhere you can't legally go, then everything's going to stop.)
    I'm trying not to delve into this too much , but in what scenario would you want to use an "address", rather than a "house"?

  10. #10
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by bluej322 View Post
    I'm trying not to delve into this too much , but in what scenario would you want to use an "address", rather than a "house"?
    Any time a function calls for an address, and not a house.

    Bu seriously, that is not too far from the truth. One significant place is when you are using functions. As C uses a pass by value scheme, i.e., when you give arguments to a function the values are "copies", you will need to pass a pointer (the address) in to the function, should you want to manipulate the value.

    For example, consider the classic case of a swap function:

    Code:
    void swap(int x, int y)
    {
        int tmp;
    
        tmp = x;    /* Wrong -- We are only working on copies of the original values */
        x = y;
        y = tmp;
    }
    
    int main(void)
    {
        int x = 5;
        int y = 2;
    
        printf("x = %d and y = %d\n", x, y);
    
        swap(x, y);
    
        printf("x = %d and y = %d\n", x, y);
    
        return 0;
    }
    The above code won't work, because the swap function is just working on copies of the variables in main. In order for it to work correctly, you need to give it access to the variables in main. The way you do this is to pass it the address of the variables (a pointer):

    Code:
    #include <stdio.h>
    
    void swap(int *x, int *y)
    {
        int tmp;
    
        tmp = *x;
        *x = *y;
        *y = tmp;
    }
    
    int main(void)
    {
        int x = 5;
        int y = 2;
    
        printf("x = %d and y = %d\n", x, y);
    
        swap(&x, &y);
    
        printf("x = %d and y = %d\n", x, y);
    
        return 0;
    }
    Last edited by kermit; 01-04-2011 at 06:04 PM.

  11. #11
    Registered User
    Join Date
    Jan 2011
    Posts
    37
    Thanks for the clarification!
    Here's another quick question. In the swap() example you used, the swap() function has the type "void", anduril directed me to a page earlier explaining the different types of functions, there it said that void function type "takes no arguments, and returns nothing". How then, was the swap function able to take an argument from main(), and then return something? Or did i just misread the definition of void function types?

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    The 'void' before the function name means it returns nothing. The (void) parameter list means it takes no parameters. They are distinct. The swap functions provided return nothing, but take two specific parameters.

  13. #13
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Well, the void indicates that the function is not returning any value. If I wanted to return an int, for example, I would have declared it:

    Code:
    int swap(int *x, int *y)
    If I was not passing any arguments into the function, then I would have used void inside the parentheses:

    Code:
    void swap(void)
    That is just as an example - as a swap function, it would not do much. Just remember, when you declare a function, you have it's return type, its name, and any arguments it takes. If you aren't returning a value, declare it as void, and if you are not passing any arguments, use void in the parentheses.

    Edit: Clearly, I cannot type fast enough. At any rate, a long time ago, I wrote a series of articles on functions in the C language. They don't really touch on pointers, but they do cover some of the basic ideas of functions fairly well. You might find it helpful to browse through them. They are the 6 chapters under "Functions."
    Last edited by kermit; 01-04-2011 at 07:08 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Polymorphism and generic lists
    By Shibby3 in forum C# Programming
    Replies: 9
    Last Post: 07-26-2010, 05:27 AM
  2. Arrays of pointers...
    By Programmer_P in forum C++ Programming
    Replies: 60
    Last Post: 05-24-2010, 09:58 AM
  3. disposing error
    By dropper166 in forum C# Programming
    Replies: 2
    Last Post: 03-30-2009, 11:53 PM
  4. Replies: 11
    Last Post: 03-24-2006, 11:26 AM
  5. adding ASCII values
    By watshamacalit in forum C Programming
    Replies: 1
    Last Post: 12-26-2002, 07:16 PM