Thread: String in C

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

    Join Date
    Dec 2012
    Posts
    17
    Rep Power
    0

    String in C


    I know there's really no strings in C. But I need some help if you may:

    #include<stdio.h>

    char password(char pass[]);

    char password(char pass[])
    {
    return pass;
    }

    May I ask, if I want to return pass what data type do I need? If I use char it errors.

    Thanks again,
  2. #2
  3. Lord of the Dance
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2003
    Posts
    3,575
    Rep Power
    1906
    string in C is really a char array.
    You can see the function accept char[], so it should return the same.
    In standard C, i think/guess that char* would be more correct.

    If you work with strings I suggest you look up how pointers work, if you haven't already.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    17
    Rep Power
    0
    Yeah. You're right. I had to go more-in-depth about pointers.

    I read in my book on C that the variable also takes a value as a pointer.

    #include<stdio.h>

    char pass(char msg[]);

    char pass(char msg[])
    {
    return *msg;
    }

    main()
    {
    printf("%s",pass("Bob"));
    getchar();
    }

    Why isn't this working? Keep in mind, my main scenerio I changed was *msg
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    OK, array names and pointers are mostly equivalent -- there are a few things that you can do with pointers that you can't do with arrays. So there shouldn't be any difference between pass(char msg[]) and pass(char *msg).

    Where you're messing up is in the return type. If you want to return a char array, you're actually returning a char pointer. The way you have pass written now, you're only returning the first char of msg, which then gets misinterpreted in the printf since you're using "%s"; if you tried "%c" instead, you should see 'B' printed -- I have no idea what you're getting now.

    This should work:
    Code:
    #include<stdio.h>
    
    char *pass(char msg[]);
    
    char *pass(char msg[])
    {
        return msg;
    }
    
    int main()
    {
        printf("%s",pass("Bob"));
        getchar();
    
        return 0;
    }
    Note that I changed the return type to char* and I removed the * in the return statement that dereferenced msg. Also, I corrected the declaration of main and added the requisite return from main.

    Look it over, think it over, and understand what's happening.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    17
    Rep Power
    0
    That worked. Thank you.

    But I'm confused why you put a pointer by the function.

    "*pass"

    Why did you put a pointer there? I didn't see you use an address of operator so does the function have its own address?

    Can you just please explain why you put a pointer there? That'll be great! ;)
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    Purely stylistic.

    char *pass
    is the same as
    char* pass
    and even as
    char*pass
    It's not saying anything about being a pointer to pass, but rather just says that this is a char pointer datatype. It's most common to write it as
    char *pass
    even though some like to place it with the char to make that more clear.

    I think the common way is due to multiple variable declarations on a single line; eg:
    char ch, *cp;
    That declares two variables: ch which is a char and cp which is a char pointer. As you can see, the * is associated with the variable name there, so that appears to be carried over to other declarations; eg, function parameter lists, function return types.

    So to reiterate, there's no difference between char *pass and char* pass. They both say the exact same thing.
    Last edited by dwise1_aol; February 13th, 2013 at 06:01 PM.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2010
    Posts
    67
    Rep Power
    0
    Code:
    #include<stdio.h>
    #include<conio.h>
    #include<string.h>
    char *password(char pass[5])
    	{
    	
    	gets(pass);
    	return pass;	
    	}
    
    int main()
    	 {
    	 	char pass[5];
    	printf("Enter password you want");
    	password(pass);
    	
    	printf("you entered %s",pass);
    
    
    	
    	 getch();
    	 return 0;
    	 }

    Comments on this post

    • ptr2void disagrees : Stop giving bad info.
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,143
    Rep Power
    2222
    @swapy: hello

    Blam! I just blew your program out of the water! Or as Da-Wei would put it, I sent it running off into the weeds to puke all over its own shoes.

    I'm quite sure that we've already warned you about using gets. I also know that most documentation on gets warns you to not use it (I know that most man pages do) and that some compilers will issue a warning when you use it (or are you ignoring warnings?).

    And I'm puzzled by your giving the array's dimension in the function header like that. Frankly, in more than 20 years experience with C/C++ I've not seen that done outside of a few people on this forum. I assume that it must work, but I don't see how it would make much difference.

    Here is a much better version:
    Code:
    #include<stdio.h>
    #include<conio.h>
    #include<string.h>
    
    #define MAX_PASS_LEN  40
    
    char *password(char *pass)
    {
        // fgets limits the input to MAX_PASS_LEN-1, thus
        //  automatically accounting for the null-terminator
        fgets(pass, MAX_PASS_LEN, stdin);	
        return pass;	
    }
    
    int main()
    {
        // normally, we would need to make pass longer than 1 in order to
        //   accommodate the null-terminator, but fgets handles that for us
        char pass[MAX_PASS_LEN];
        
        printf("Enter password you want: ");
        
        // what's actually happening here is that we are throwing away 
        //   the return value and receiving the change through the char
        //   pointer we passed to the function (array name acts as a pointer)
        // However, if we had done this:
        //      printf("you entered %s\n",password(pass));
        //   then we would still have received the change the same way,
        //   but now the returned char pointer is used by printf.
        //   This is just about the only reason to return the pointer,
        //      but it is a good reason and hence good practice.
        password(pass);
    	
        printf("you entered %s\n",pass);
    	
        // only needed if you aren't running this from the shell's command line.
        getch();
        
        return 0;
    }
    PS
    My reply was primarily to address your implicit recommendation to use gets. Here is what the GNU C Library help file says:
    Deprecated function: char * gets (char *s)

    The function gets reads characters from the stream stdin up to the next newline character, and stores them in the string s. The newline character is discarded (note that this differs from the behavior of fgets, which copies the newline character into the string). If gets encounters a read error or end-of-file, it returns a null pointer; otherwise it returns s.

    Warning: The gets function is very dangerous because it provides no protection against overflowing the string s. The GNU library includes it for compatibility only. You should always use fgets or getline instead. To remind you of this, the linker (if using GNU ld) will issue a warning whenever you use gets.
    When a buffer overflow occurs, the memory after the buffer get overwritten, AKA "clobbered". When this happens inside of a function (even main is a function), then that can destroy information that it vital to the execution of that function, including the address that it is to return to. This will most commonly lead to the program crashing.

    But even worse, such careless programming leaves your program open to buffer overflow exploits, a common method for hackers to take over your system. Sure, the most malicious thing a hacker could do to your student program is to cause it to crash, but if you continue your careless practices in writing commercial software, then a hacker will find that buffer overflow and create an exploit tailored to it, one which will "return" to code embedded in the overflow input, the "payload", that will either take over or destroy that system. At best, it will allow the hacker to do a denial of service attack by causing the system to crash.

    Learn as early as you can to program correctly and robustly.
    Last edited by dwise1_aol; February 14th, 2013 at 12:05 PM.

IMN logo majestic logo threadwatch logo seochat tools logo