Thread: Help - String input header

  1. #1
    Registered User
    Join Date
    Aug 2008
    Posts
    55

    Help - String input header

    What I want to do is to get a string from input without having to guess at the size of the array needed beforehand, and be able to concatenate a new input string on the end of it, something like this:
    Code:
    char * str = instring();  //get string from input allocating just enough space for it
    incat(str);                    //concatenate a new string to the end of str
    My header file so far:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char * instring(){
        char * str = (char *) malloc(sizeof(char));
        str[0] = '\0';
    
        int c;		//char to be put into 
        int i = 0;		//index of string to store
    
        while((c = getchar()) != '\n'){
    	str[i] = c;
    	str = (char *)realloc(str, (i+2) * sizeof(char));
    	str[i+1]='\0';
    
    	i++;
    
        }
        return str;
    }
    
    
    
    void incat(char * str1){
    	char * instr = instring();
    	int newlength = strlen(str1) + strlen(instr)
    
    	str1 = (char *)realloc(str1, (newlength + 1) * sizeof(char));
    
    	strcat(str1, instr);
    }
    instring seems to work all the time, but incat is not right. It seems to work for shorter strings, but strangness occurs on longer ones. Any help would be appreciated.

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Of course it doesn't work.

    Who said the pointer returned by realloc() is going to be what you passed it? No one.
    Perhaps you wanted:
    Code:
    void incat(char ** str1)
    {
        /* ... */
    
       *str1 = realloc(*str1, ...);
    
       strcat(*str1, instr);
    }
    Some tips:
    1. sizeof(char) is always 1. So just omit it.
    2. free() memory when you're done.
    3. You should consider reading say 256 bytes, then realloc() another 256 if you need it (say there is still more data in the buffer). This is much faster than doing 256 realloc()'s. You could do this with fgets() and some error checking.
    4. You may hit EOF before you hit a new line.
    5. Don't cast malloc()/realloc()/calloc() in C.
    Last edited by zacs7; 06-09-2009 at 08:44 PM.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Are you sure you've giving us the code you're working with? 2nd line in incat() is lacking a semicolon.

  4. #4
    Registered User
    Join Date
    Aug 2008
    Posts
    55
    Quote Originally Posted by MacGyver View Post
    Are you sure you've giving us the code you're working with? 2nd line in incat() is lacking a semicolon.
    After I posted the code I saw that a bunch of extra space was added so I edited it out, but I must have accidentally gotten a semicolon.

    zacs7- thanks for the tips. I realize the pointer returned by realloc could point to a different location than str originally pointed to, but wouldn't the new address be assigned to the str pointer in the code I had? Maybe it's a stupid question but I don't quite get it.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Pointers store values.
    You can't change the value of something you pass to a function, unless you instead pass its address.
    Thus, to change the value of a pointer (read: what it's actually pointing at, not the value of what is being pointed at), you need to pass the address of that pointer.

    Consider:

    To change an int's value, you pass its address. This way you can make it keep the value changes you do inside the function.
    To change a pointer's value, you pass its address.

    So, to make a pointer point elsewhere, you need a pointer to a pointer.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    No function can change the value of an input parameter for good. If you want to be able to change a value (such as str), you need to pass in a pointer to that value. (Yes, str is a pointer, but it is not a pointer to the thing you want to change.)

  7. #7
    Registered User
    Join Date
    Aug 2008
    Posts
    55
    Quote Originally Posted by quzah View Post
    Pointers store values.
    You can't change the value of something you pass to a function, unless you instead pass its address.
    Thus, to change the value of a pointer (read: what it's actually pointing at, not the value of what is being pointed at), you need to pass the address of that pointer.

    Consider:

    To change an int's value, you pass its address. This way you can make it keep the value changes you do inside the function.
    To change a pointer's value, you pass its address.

    So, to make a pointer point elsewhere, you need a pointer to a pointer.


    Quzah.
    Ahh, thats right, I get it now. Thanks.

  8. #8
    Registered User
    Join Date
    Aug 2008
    Posts
    55
    I changed incat() so that it returns char * so I can do something like
    Code:
    str = incat(str);
    That works fine if str was initialized by instring(), but something like
    Code:
    char * str = "Hello";
    str = incat(str);
    won't work. Why is that?


    And a couple quick questions about zacs7s' post.
    Quote Originally Posted by zacs7 View Post
    Some tips:
    1. sizeof(char) is always 1. So just omit it.
    It wouldn't be 2 if you're working with unicode?
    Quote Originally Posted by zacs7 View Post
    5. Don't cast malloc()/realloc()/calloc() in C.
    The examples I've seen online and in books have used a cast, if I remember correctly the reason my c book gave was that it isn't required in c but is in c++ so you might as well put it in in case you bring it to c++ at some point. Why shouldn't you cast it in C?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Nextstopearth
    The examples I've seen online and in books have used a cast, if I remember correctly the reason my c book gave was that it isn't required in c but is in c++ so you might as well put it in in case you bring it to c++ at some point. Why shouldn't you cast it in C?
    Unlike C++, C allows you to call functions without declaring them, in which case their return types and parameter types are assumed to be int. So, if you did not #include <stdlib.h> and set a high enough warning level, you would be able to compile code that casts the return value of malloc(), even though what is returned is an int instead of a pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    If you don't include stdlib.h, wouldn't the code just refuse to compile and say something like

    "undefined implicit reference to builtin function malloc()" ?

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Nope, "implicit calls" are legal in C, as opposed to C++.
    (Were they legal in C99, again? I can't remember.)
    Some compilers will spit out a warning if you do this, but a lot of compiler will not, so it's usually good practice not to cast the return to give yourself (and the compiler) an extra opportunity to catch such mistakes!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 03-24-2006, 11:26 AM
  2. c++ string input
    By R.Stiltskin in forum C++ Programming
    Replies: 4
    Last Post: 02-22-2003, 04:25 PM
  3. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  4. ........ed off at functions
    By Klinerr1 in forum C++ Programming
    Replies: 8
    Last Post: 07-29-2002, 09:37 PM