inputting strings.

Discussion in 'C Programming' started by Kruton, Sep 13, 2003.

  1. Kruton

    Kruton Guest

    What is the easiest way to take a string from a console while including
    whitespaces? This program's user will input a line of text that will
    consist of multiple tokens, but the number tokens and the length of each
    line will vary at each use. Is there a way to get scanf to take a string
    that contains whitespace? Or is there another function that would work?
    -Thank you
    Kruton, Sep 13, 2003
    #1
    1. Advertising

  2. On Sat, 13 Sep 2003 02:56:37 -0500
    "Kruton" <> wrote:
    > What is the easiest way to take a string from a console while including
    > whitespaces? This program's user will input a line of text that will
    > consist of multiple tokens, but the number tokens and the length of each
    > line will vary at each use. Is there a way to get scanf to take a string
    > that contains whitespace? Or is there another function that would work?
    > -Thank you


    #include <stdio.h>
    char buffer[bufsize];
    fgets(buffer, bufsize, stdin);

    Will read one line of text from standard input. Returns NULL on error or EOF, or
    a pointer to the buffer on success.
    Note that the newline is stored as well.

    --
    char*x(c,k,s)char*k,*s;{if(!k)return*s-36?x(0,0,s+1):s;if(s)if(*s)c=10+(c?(x(
    c,k,0),x(c,k+=*s-c,s+1),*k):(x(*s,k,s+1),0));else c=10;printf(&x(~0,0,k)[c-~-
    c+"1"[~c<-c]],c);}main(){x(0,"^[kXc6]dn_eaoh$%c","-34*1'.+(,03#;+,)/'///*");}
    Pieter Droogendijk, Sep 13, 2003
    #2
    1. Advertising

  3. "Kruton" <> writes:

    > What is the easiest way to take a string from a console while including
    > whitespaces?


    /* ******** ex ****** */
    #include<stdio.h>

    int main(void){
    char buffer[200];
    printf("Write the string : ");
    fgets(buffer,200,stdin);
    printf("The string you wrote was : %s",buffer);
    return 0;
    }
    /* ****************** */

    bye.
    Nicola Mingotti, Sep 13, 2003
    #3
  4. Kruton

    pete Guest

    Kruton wrote:
    >
    > What is the easiest way to take a string from a
    > console while including whitespaces?
    > This program's user will input a line of text that will
    > consist of multiple tokens, but the number tokens and the
    > length of each line will vary at each use.
    > Is there a way to get scanf to take a string
    > that contains whitespace?


    /* BEGIN new.c */

    #include <stdio.h>

    #define STRINGLENGTH 160
    #define str(x) # x
    #define xstr(x) str(x)

    int main(void)
    {
    char string[STRINGLENGTH] = {0};
    int rc;

    fputs("Enter a string with spaces: ", stdout);
    fflush(stdout);
    rc = scanf("%" xstr(STRINGLENGTH) "[^\n]%*[^\n]", string);
    getchar();
    if (rc > 0) {
    printf("\nYour string is:\n\"%s\"\n", string);
    }
    return 0;
    }

    /* END new.c */


    --
    pete
    pete, Sep 13, 2003
    #4
  5. Kruton

    Al Bowers Guest

    pete wrote:
    > Kruton wrote:
    >
    >>What is the easiest way to take a string from a
    >>console while including whitespaces?
    >>This program's user will input a line of text that will
    >>consist of multiple tokens, but the number tokens and the
    >>length of each line will vary at each use.
    >>Is there a way to get scanf to take a string
    >>that contains whitespace?

    >
    >
    > /* BEGIN new.c */
    >
    > #include <stdio.h>
    >
    > #define STRINGLENGTH 160
    > #define str(x) # x
    > #define xstr(x) str(x)
    >
    > int main(void)
    > {
    > char string[STRINGLENGTH] = {0};
    > int rc;
    >
    > fputs("Enter a string with spaces: ", stdout);
    > fflush(stdout);
    > rc = scanf("%" xstr(STRINGLENGTH) "[^\n]%*[^\n]", string);


    STRINGLENGTH-1.
    The array string is not large enough to accept 160 chars plus a
    nul-terminating character. That would be 161.


    > getchar();
    > if (rc > 0) {
    > printf("\nYour string is:\n\"%s\"\n", string);
    > }
    > return 0;
    > }


    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x)
    http://www.geocities.com/abowers822/
    Al Bowers, Sep 13, 2003
    #5
  6. Kruton

    pete Guest

    Al Bowers wrote:
    >
    > pete wrote:
    > > Kruton wrote:
    > >
    > >>What is the easiest way to take a string from a
    > >>console while including whitespaces?
    > >>This program's user will input a line of text that will
    > >>consist of multiple tokens, but the number tokens and the
    > >>length of each line will vary at each use.
    > >>Is there a way to get scanf to take a string
    > >>that contains whitespace?

    > >
    > >
    > > /* BEGIN new.c */
    > >
    > > #include <stdio.h>
    > >
    > > #define STRINGLENGTH 160
    > > #define str(x) # x
    > > #define xstr(x) str(x)
    > >
    > > int main(void)
    > > {
    > > char string[STRINGLENGTH] = {0};
    > > int rc;
    > >
    > > fputs("Enter a string with spaces: ", stdout);
    > > fflush(stdout);
    > > rc = scanf("%" xstr(STRINGLENGTH) "[^\n]%*[^\n]", string);

    >
    > STRINGLENGTH-1.
    > The array string is not large enough to accept 160 chars plus a
    > nul-terminating character. That would be 161.


    Thank you.

    I meant to write:

    char string[STRINGLENGTH + 1] = {0};

    since the length of a string,
    is one less than the total number of bytes.

    --
    pete
    pete, Sep 14, 2003
    #6
  7. Kruton

    Simon Biber Guest

    "Nicola Mingotti" <> wrote:
    > #include<stdio.h>
    >
    > int main(void){
    > char buffer[200];
    > printf("Write the string : ");


    You need to add a flush here to ensure that the prompt appears on the
    screen before the system starts waiting for input.
    fflush(stdout);

    > fgets(buffer,200,stdin);


    Magic number alert - very bad idea. Use
    fgets(buffer, sizeof buffer, stdin);
    That way you can change the buffer size in one place only.

    You should also check whether the fgets returned a null pointer. If
    so, it is undefined behaviour to try to print buffer.

    > printf("The string you wrote was : %s",buffer);


    If the user typed a string longer than 199 characters there will be
    no newline character stored at the end of the buffer, which means the
    stdout stream may not be valid, as it is not terminated properly.

    > return 0;
    > }


    --
    Simon.
    Simon Biber, Sep 14, 2003
    #7
  8. On Sat, 13 Sep 2003 07:56:37 UTC, "Kruton" <> wrote:

    > What is the easiest way to take a string from a console while including
    > whitespaces? This program's user will input a line of text that will
    > consist of multiple tokens, but the number tokens and the length of each
    > line will vary at each use. Is there a way to get scanf to take a string
    > that contains whitespace? Or is there another function that would work?


    getc() or getchar() is what you're looking for.

    If your parser is simple you will write it on your own, else you may
    use yacc/bison as a parser generator. Both uses getc() to have direct
    access to the stream to avoid dynamic buffers.

    Get a char, check it against the ones you will accept in the state you
    are currently and when needed change the state.

    You can easy accept token after token without a buffer (except the
    token itself requires some kind of). You can convert any numerical
    value on the fly wheras you sees any error directly.

    You can use fscanf() or other library functions only if you sure that
    you have a trusted input. But trusted input is only possible when you
    accepts only files written by a well tested program.

    Ever when you have to read anything from stdin you are sure that your
    input is really untrusted and brings anything wrong. But no library
    function will be ready to read any possible wrong things.

    Even gets() tends to buffer overflow!

    It will be more easy to write a little parser that reads char by chare
    and acts on it as to handle a buffer that may be always to short to
    get anything:
    - you awaits a maximum line lengh of 80: the input is 81 - buffer
    overflow or extra handling to extend the buffer until you have a
    complete line readed in
    - you awaits a maximum line length of 132: ther are 32K without '\n'
    waiting in the stream.
    - You awaits 32K - but the stream has 2GB without '\n'

    You can't never handle all possible errors with the higher level
    standard library functions.

    Using token tables, getc()/getchar() makes it quite easy to extend the
    functionality of your program without rewriting anything when you have
    to handle a new token or change the token parameters.

    ungetc() is designed to put a single char back into the input stream -
    but the character you puts back can be any charater - not only the one
    you've readed last!

    Even as ungetc() is designed to put a single character it is not too
    hard to write a wrapper around gtc()/ungetc to stack more than one
    back. Yes, you must then use only the wrapper to read - but macros are
    your friends anyway.

    At least getc() is in no ways slower than (f)gets(), scanf() or
    whatever, because all of them use getc() internally.
    As you have to tokenise the stream you will win some runtime when you
    use getc() directly, because you saves the (formatted) copy from one
    puffer to another and scan that new puffer again (multiple times). You
    can bring each char ito its real destionation and format on the fly
    instead.

    O.k., you may have some extra overhead to handle states - but make a
    well design before you starts coding and you gets more flexibility for
    free - and you saves the overhead the higher leveld library brings
    with:
    - dynamic buffer only to get a complete line
    malloc() is a source of errors you have to handle
    - breaking the line into tokens by copying the data partially from the
    input buffer into another buffer
    temp (buffer) -> destination field or another temp to convert from
    string to something else
    - checking the results of the library functions to make something
    strange to come around

    --
    Tschau/Bye
    Herbert

    eComStation 1.1 Deutsch Beta ist ver├╝gbar
    The Real OS/2 Guy, Sep 14, 2003
    #8
  9. "Simon Biber" <> writes:

    > "Nicola Mingotti" <> wrote:
    > > #include<stdio.h>
    > >
    > > int main(void){
    > > char buffer[200];
    > > printf("Write the string : ");

    >
    > You need to add a flush here to ensure that the prompt appears on the
    > ....


    sure , i do agree with you :)
    anyway the example was written to be
    *very* simple ...
    but it's true , i had to tell it ;)

    bye.
    Nicola Mingotti, Sep 15, 2003
    #9
  10. Kruton

    MikeyD Guest

    "Kruton" <> wrote in message
    news:p...
    > What is the easiest way to take a string from a console while including
    > whitespaces? This program's user will input a line of text that will
    > consist of multiple tokens, but the number tokens and the length of each
    > line will vary at each use. Is there a way to get scanf to take a string
    > that contains whitespace? Or is there another function that would work?
    > -Thank you


    Well, the *easy* way is the gets(char[]) function to put text into an array,
    but that has the minor disadvantage that if a user enters too long a string
    you will overwrite your program's return value, which could leave you going
    anywhere. A merely incompetent user might crash the kernel. A malicious one
    could, in theory at least, execute arbitrary program code downloaded from
    the internet.
    If you're using gcc, there's a nice function called get_line() that will
    automatically expand the string with malloc if someone enters a longer line.
    Of course you have to create the char vector as dynamic memory, and this is
    incompatiable with other compilers
    Most people will use fgets(FILE*,char[],int), which reads input but won't go
    outside the array. However, it makes you specify stdin each time and won't
    delete the trailing \n.
    If you know what you want it for, I'd recommend you write your own
    getstring(char[],int) function, which lets you choose your own terminator
    value, error messages etc. Here's mine as an example (with a few #defines
    for you to customize)
    #include <stdio.h>
    #define TERMINATOR '\n'
    #define SUCCESS 1
    #define FAIL 0
    //if you want to return the number of characters read
    //#define CHARS
    //if you want a printed error message when too much is entered
    //#define MSG
    int getstring(char* a, int len){
    for(int i=0;;i++){
    a=getchar();
    if(a==TERMINATOR){
    a='\0';
    #ifdef CHARS
    return i;
    #else
    return SUCCESS
    #endif
    }
    if(i==len){
    a='\0';//to give a proper string even though it won't contain
    all the input
    #ifdef MSG
    fprintf(stderr,"Error: Invalid string: Too many characters before
    TERMINATOR")
    //replace TERMINATOR manually, probably with "ENTER"
    #endif
    return FAIL;
    }
    }
    }
    MikeyD, Sep 16, 2003
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bill

    Inputting NULLS?

    Bill, Dec 11, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    353
    Suresh
    Dec 11, 2003
  2. Aaron

    Error on inputting data

    Aaron, Jan 1, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    2,776
    Peter Blum
    Jan 2, 2006
  3. =?Utf-8?B?amFzb253b25n?=

    Inputting Text to the Runtime Parser

    =?Utf-8?B?amFzb253b25n?=, Jan 13, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    357
    =?Utf-8?B?amFzb253b25n?=
    Jan 13, 2006
  4. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    735
    Malcolm
    Jun 24, 2006
  5. Replies:
    4
    Views:
    396
    Noclambulist
    Feb 27, 2006
Loading...

Share This Page