Thread: get input string

  1. #1
    Registered User
    Join Date
    Feb 2003
    Posts
    3

    Smile get input string

    hi all,

    how can i get an input string with an unknown size ?


    tnx
    m_g

  2. #2
    Registered User Vber's Avatar
    Join Date
    Nov 2002
    Posts
    807
    for getting strings from an stream, search out about the fgets() function.

  3. #3
    Registered User
    Join Date
    Feb 2003
    Posts
    3
    hi vber,

    tnx for your quick answer, i've took a look to fgets, but seem that
    you have to set a maximum number of character, i was looking for something that doesn't care about size of input string.

    char *fgets(char *BUF, int N, FILE *FP);

    DESCRIPTION
    Reads at most N-1 characters from FP until a newline is found. The characters including to the newline are stored in BUF. The buffer is terminated with a 0.




    by
    m_g

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >how can i get an input string with an unknown size ?
    You have to be careful about it when it comes to unknown sized strings. The most commonly used way is to dynamically allocate memory for a string and if you run out of memory, realloc it:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BASE 256
    #define STEP ( BASE + 256 ) /* Or whatever suits you */
    
    static char *readline ( FILE *f )
    {
      size_t size, nread;
      char *buf, *save, *read;
      
      if ( ( buf = malloc ( BASE ) ) == NULL )
        return NULL;
    
      size = nread = BASE;
      read = buf;
      
      if ( fgets ( read, nread, f ) == NULL ) {
        free ( buf );
        return NULL;
      }
    
      while ( ( save = strchr ( read, '\n' ) ) == NULL ) {
        nread = STEP + 1;
        size += STEP;
    
        if ( ( save = realloc ( buf, size ) ) == NULL )
          return buf;
    
        buf = save;
        read = buf + ( size - STEP - 1 );
        
        if ( fgets ( read, nread, f ) == NULL ) {
          free ( buf );
          return NULL;
        }
      }
      
      *save = '\0';
      nread = save - buf;
    
      if ( ( save = realloc ( buf, nread + 1 ) ) == NULL )
        return buf;
      
      return save;
    }
    
    int main ( void )
    {
      char *p = readline ( stdin );
      
      puts ( p );
      free ( p );
      
      return 0;
    }
    -Prelude
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Feb 2003
    Posts
    3
    thank you all guys!

    by
    m_g

  6. #6
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    Use realloc , or use a linked list
    One possible solution

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    char *addc(char *s,char c,int i)
    {
            char *tmp;
            if(!s) 
            {
                    s=malloc(1);
                    if(!s)
                    {
                            perror(NULL);
                            exit(1);
                    }
                    s[0]=c;
                    return s;
            }
            tmp=realloc(s,i+1);
            if(tmp)
            {
                 s=tmp;
                 s[i]=c;
            }
            else
            {
                 perror(NULL);
                 exit(1);
            }
            i++;
            return s;
    }
    
    int main(void)
    {
            char *str=0,c,*tmp;
            int i=0;
            while( (c=getchar()) != EOF)
            {
                    str=addc(str,c,i++);
            }
            str=addc(str,0,i);
            printf("str=%s",str);
            return 0;
    }
    $echo 11223 | ./ a.out
    $str=11223
    The one who says it cannot be done should never interrupt the one who is doing it.

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    @pinko_liberal
    A couple of comments:

    malloc'ing one byte of memory at a time is a relatively expensive way of doing business. It would be better to malloc in chunks in a real app (ie not a demo, like this one)

    >>i++;
    This achieves nothing, as you don't use i after incrementing it.

    >>char c;
    >>while( (c=getchar()) != EOF)
    getchar() returns an int, not a char.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    You are right, I wonder how I could have declared c a char, reallocing in chucks is always better of course, but this was just a quick and dirty program.
    Originally posted by Hammer
    @pinko_liberal
    A couple of comments:

    malloc'ing one byte of memory at a time is a relatively expensive way of doing business. It would be better to malloc in chunks in a real app (ie not a demo, like this one)

    >>i++;
    This achieves nothing, as you don't use i after incrementing it.

    >>char c;
    >>while( (c=getchar()) != EOF)
    getchar() returns an int, not a char.
    The one who says it cannot be done should never interrupt the one who is doing it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Replies: 14
    Last Post: 01-18-2008, 04:14 PM
  3. Replies: 4
    Last Post: 03-03-2006, 02:11 AM
  4. can anyone see anything wrong with this code
    By occ0708 in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 12:47 PM
  5. lvp string...
    By Magma in forum C++ Programming
    Replies: 4
    Last Post: 02-27-2003, 12:03 AM