String problem, I guess?

Discussion in 'C Programming' started by Paul Hobbs, Jul 31, 2006.

  1. Paul Hobbs

    Paul Hobbs Guest

    Hi,

    I wanted to create a function which forced a user to enter no more than a
    specified number of characters. The code for this is below. The idea was
    simple, if a user is only meant to enter 10 characters it would throw away
    any remaining characters. This works fine upto10 characters for example:

    C:\> getstring
    Command : 123456789
    Command [123456789] :


    However when you enter more than 10 characters it does this:

    C:\> getstring
    Command [1234567890] : 12345678901
    Command [1234567890] : Command [1234567890] :


    Why does it display the command line twice, I've read about the fflush
    command but this does not help, does anyone have any ideas.

    Many Thanks
    Paul


    #define MAX_COMMAND_LEN 11

    #include <stdio.h>
    #include <string.h>
    #include <conio.h>
    #include <ctype.h>


    /* Function prototypes. */
    void init_string(char *string);
    void get_string(char *string,int length,char *prompt);


    int main(void) {

    char command[MAX_COMMAND_LEN];

    /* Initialise string. */
    init_string(command);


    /* Allow user input util the user enters the command 'EXIT'. */
    do {
    get_string(command,MAX_COMMAND_LEN,"Command");
    } while (stricmp(command,"EXIT") != 0);

    return 0;

    }


    /* Get input of a griven string with a specified number of characters. */
    void get_string(char *string,int length,char *prompt) {

    /*
    ** I've adjusted the length of the string read by 1, so that in the
    event
    ** of the user entering the exact number of characters, the last
    character
    ** will not be truncated. This occurs because fgets() adds a '\n' +
    '\0' to
    ** the end of the string. The additional character is only required
    ** temporally to allow the replacement of '\n' with '\0'.
    **
    ** Example: get_string(postcode,8,"Post Code");
    **
    ** Once the user has pressed return.
    **
    ** +---+---+---+---+---+---+---+----+----+
    ** | B | 1 | 3 | | 0 | D | B | \n | \0 |
    ** +---+---+---+---+---+---+---+----+----+
    **
    ** After replacing the '\n' character with a '\0' character.
    **
    ** +---+---+---+---+---+---+---+----+
    ** | B | 1 | 3 | | 0 | D | B | \0 |
    ** +---+---+---+---+---+---+---+----+
    **
    ** If I did not adjust the number of characters read this happens.
    **
    ** +---+---+---+---+---+---+----+----+
    ** | B | 1 | 3 | | 0 | D | \n | \0 |
    ** +---+---+---+---+---+---+----+----+
    **
    ** And then after replacing the '\n' character with a '\0' character.
    **
    ** +---+---+---+---+---+---+----+
    ** | B | 1 | 3 | | 0 | D | \0 |
    ** +---+---+---+---+---+---+----+
    **
    */

    char defvalue[80];

    /* Make current value available as a default value. */
    strcpy(defvalue,string);

    /* Check if the user specified a prompt to be displayed. */
    if (strcmp(prompt,"") != 0) {
    /* If the string has a previous value then display it as a default.
    */
    if (strcmp(string,"") != 0) {
    printf("%s [%s] : ",prompt,string);
    } else {
    printf("%s : ",prompt);
    }
    }

    /* Accept user input and replace the '\n' with '\0'. */
    fgets(string,length+1,stdin);
    string[strlen(string)-1] = '\0';

    /* If the user pressed RETURN use the default value. */
    if (strcmp(string,"") == 0) {
    strcpy(string,defvalue);
    }

    }


    /* Initialise the string. */
    void init_string(char *string) {

    strcpy(string,"");

    }
    Paul Hobbs, Jul 31, 2006
    #1
    1. Advertising

  2. Paul Hobbs said:

    > Hi,
    >
    > I wanted to create a function which forced a user to enter no more than a
    > specified number of characters. The code for this is below. The idea was
    > simple, if a user is only meant to enter 10 characters it would throw away
    > any remaining characters. This works fine upto10 characters for example:
    >
    > C:\> getstring
    > Command : 123456789
    > Command [123456789] :
    >
    >
    > However when you enter more than 10 characters it does this:
    >
    > C:\> getstring
    > Command [1234567890] : 12345678901
    > Command [1234567890] : Command [1234567890] :
    >
    >
    > Why does it display the command line twice,


    Once for each fgets call, because you forgot something rather important.

    The fgets function retrieves up to n - 1 characters from the stream you tell
    it to read, where n is the number you tell it. (n - 1 so that it knows it
    can safely stick a '\0' on the end.) As soon as it copies '\n' into the
    buffer, it nails on a terminator and returns - BUT if it copies n - 1
    characters from the stream and still hasn't read a '\n' yet, it stops,
    terminates the string, and returns.

    So you need to detect the newline. If it's present, all is well, and you can
    proceed as planned. But if it is *not* present (as will be the case if the
    user enters 12345678901), then you must decide whether to process the
    string at all. I would guess you want to say something like "command too
    long - retry". Having done that, you need to keep calling fgets in a loop,
    until eventually you find a '\n' in the string. Then and only then, you can
    print your prompt and wait for the next command.

    > I've read about the fflush
    > command but this does not help, does anyone have any ideas.


    fflush handles output, not input, so it's of no help here.

    <snip>

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
    Richard Heathfield, Jul 31, 2006
    #2
    1. Advertising

  3. Paul Hobbs

    pete Guest

    Paul Hobbs wrote:
    >
    > Hi,
    >
    > I wanted to create a function which forced
    > a user to enter no more than a specified number of characters.
    > The code for this is below. The idea was simple,
    > if a user is only meant to enter 10 characters it would throw away
    > any remaining characters.


    /* BEGIN pops_device.c */
    /*
    ** If rc equals 0, then an empty line was entered
    ** and the array contains garbage values.
    ** If rc equals EOF, then the end of file was reached.
    ** If rc equals 1, then there is a string in array.
    ** Up to LENGTH number of characters are read
    ** from a line of a text file or stream.
    ** If the line is longer than LENGTH,
    ** then the extra characters are discarded.
    */
    #include <stdio.h>

    #define LENGTH 10
    #define str(x) # x
    #define xstr(x) str(x)

    int main(void)
    {
    int rc;
    char array[LENGTH + 1];

    puts("The LENGTH macro is " xstr(LENGTH));
    fputs("Enter a string with spaces:", stdout);
    fflush(stdout);
    rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
    if (!feof(stdin)) {
    getchar();
    }
    while (rc == 1) {
    printf("Your string is:%s\n\n"
    "Hit the Enter key to end,\nor enter "
    "another string to continue:", array);
    fflush(stdout);
    rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
    if (!feof(stdin)) {
    getchar();
    }
    if (rc == 0) {
    *array = '\0';
    }
    }
    return 0;
    }

    /* END pops_device.c */


    --
    pete
    pete, Aug 1, 2006
    #3
    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. berthelot samuel
    Replies:
    5
    Views:
    312
    Marcin Kalicinski
    Jun 17, 2004
  2. Paul Hobbs

    String problem, I guess?

    Paul Hobbs, Jul 31, 2006, in forum: C++
    Replies:
    0
    Views:
    393
    Paul Hobbs
    Jul 31, 2006
  3. Jukka K. Korpela
    Replies:
    1
    Views:
    401
    William Gill
    Sep 15, 2010
  4. MG
    Replies:
    0
    Views:
    403
  5. Doug Miller
    Replies:
    0
    Views:
    418
    Doug Miller
    Sep 15, 2010
Loading...

Share This Page