tags:

views:

286

answers:

5

I would like to know how to read a string from Standard input of length 'n'. I tried out using fgets() function but had a problem if I submit a string of length > n

#include <stdio.h>

int STRING_SIZE=4;
int getString(char *);

int getString(char *str)
{
   printf("\nEnter a string of length < %d: ", STRING_SIZE);
   fgets(str, STRING_SIZE, stdin);
   fflush(stdin);
   printf("\n\n%s\n\n",str);
   return 0;
}


int main(void)
{

   char str1[1024];
   char str2[1024];

   getString(str1);
   getString(str2);

   fprintf(stdout, "%s\n", str1);
   fprintf(stdout, "%s\n", str2);

   return 0;
}

if I enter a string of size more than 4 for str1 then the remaining characters are getting automatically allocated to str2.

So is there a way where I can give strings to both str1, str2 even after giving string > STRING_SIZE?

I am using a GCC 4.3 compiler and if I compile above source code

$ ./a.out 

Enter a string of length < 4: 12345678


123


Enter a string of length < 4: 

456

123
456
+1  A: 

Make sure you allocate str1 and str2 properly.

char str1[STRING_SIZE];
char str2[STRING_SIZE];

Also, keep in mind that fgets will null-terminate your string, so you're really only getting STRING_SIZE - 1 characters.

Andrew Keeton
Hi AndrewI am just adding up the code. I think I am just doing it properly as you mentioned it.
codingfreak
+1  A: 

Use getch in a loop.

Crimson
getch is not a standard function, getc/fgetc is.
Robert Gamble
+2  A: 

One strategy is to check your string for the presence of a newline; if you don't find one, then your user potentially entered a string that's too long for the target buffer. In that case, you can repeatedly call fgets() with a second, dummy buffer as the target and throw away the spurious input:

if (fgets(str, STR_SIZE, stdin) != NULL)
{
  char *nl = strchr(str, '\n');
  if (nl == NULL)
  {
    /**
     * Newline not found, input string too long for target buffer.
     * Repeatedly read from input stream into a dummy buffer
     * until newline is seen or fgets() returns EOF or error.  
     */
    char dummy[STR_SIZE];
    char *r;

    printf("Warning - input string longer than expected, ignoring excess characters\n");

    do {
      r = fgets(dummy, sizeof dummy, stdin);
    } while (r != NULL && strchr(dummy, '\n') == NULL);
  }
  else
  {
    /**
     * Input string is okay, remove newline character
     */
    *nl = 0;
  }
}
else
{
  /**
   * EOF or error detected on read; handle that here
   */
}
John Bode
Thanks John really very informative and easy method ....
codingfreak
A: 

Give this a shot, using getc() instead of gets(). I did some quick testing on OS X. I made a few other changes that don't matter too much. You should be able to spot them. The one thing that does matter is the change to the getString() definition: note the len argument that specifies the size of the char * buffer.

#include <stdio.h>

#define MAX_LEN 8
#define STRING_LEN 6

int getString(char *str, int len)
{
        int n_read = 0;
        int c;
        int m_len = MAX_LEN;

        if (len < m_len) m_len = len;

        printf("\nEnter a string of length < %d: ", MAX_LEN);

        while ( (n_read < len) && (c = getc(stdin)) && c!= EOF && c!='\n') {
                if (n_read < m_len-1) {
                        str[n_read++] = c;
                }
        }
        str[n_read] = '\0';

        return n_read;
}

int main(int argc, char **argv)
{
        char str1[STRING_LEN];
        char str2[STRING_LEN];

        getString(str1, STRING_LEN);
        getString(str2, STRING_LEN);

        fprintf(stdout, "%s\n", str1);
        fprintf(stdout, "%s\n", str2);

        return 0;
}
Rob Jones
Thats seems to be working with my initial tests Rob ..... thanks for the reply
codingfreak
A: 

With the answers given by "Rob Jones" and "John Bode" I have come up with a intermediate solution.

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

#define BUF_SIZE 6
#define STRING_SIZE 4

/*
 * void getStringStdin(char *, int , int );
 *
 * 1: BUF        :Pointer to the array of characters where input string is to be stored.
 * 2: BUF_LEN    :Is the length of the rray of characters where the string is stored.buffer where we save the string.
 * 3: STRING_LEN :Is the length of the string.
 *
 * NOTE: STRING_LEN < BUF_LEN
 *
*/

getStringStdin(char *buf, int buf_len, int str_len)
{

  int ch;
  char *s;
  int len;

  if(str_len>=buf_len)
  len=buf_len-1;
  else
  len=str_len;

  printf ("\nEnter string of length %d(Remaining part is ignored) : ",len);

  if( (fgets(buf, len+1, stdin)) != NULL )
  {
    s=my_strchr(buf,'\n');

    if(s!=NULL)
    {
      *s='\0';
    }
    else
    {
       while ((ch = getchar()) != '\n' && ch != EOF);
    }
  }
}


    int main(void)
    {
      int i=0;
      char buf[BUF_SIZE];

      do
      {
            getString(buf, BUF_SIZE, STRING_SIZE);
            printf ("\nString : %s\n", buf);
            i++;
      }while(i<2);

      return 0;
    }
codingfreak
What happens if STRING_SIZE is greater than BUF_SIZE? The 'len' argument should be used to specify the length (size) of the 'buf' parameter to getString(). Try making STRING_SIZE '7' and type in seven or more characters.
Rob Jones
Nice input Rob Jones so I have done the code changes accordingly
codingfreak