Issues while getting user input in SCO Unix OS

85 Views Asked by At

I face a strange issue while trying to get user input through my code. I am pretty sure that the issue is not with the code but related to OS like standard input stream (stdin) or something like that, but since I don't have another machine with similar OS setup (as it's practically impossible to find an SCO machine nowadays), I expect some programmatic workarounds to solve this. My program reads a stream of alphanumeric characters from the user terminated by a '\n'.

But no matter how I try this to achieve this by different means, it just accepts the initial 256 characters. Initially I suspected the issue is with the fgets function , but when I use try to read the same value from a file using fgets, its working as expected.

Approach 1:

main()
{
  char szInLine[999]; 
  memset(szInLine, 0, sizeof(szInLine));

  fprintf(stdout, "\nPlease enter the encrypted value:\n");

  if (fgets(szInLine, 997, stdin) == NULL)
   return(1);

  fprintf(stdout, "Encrypted data string contains %i characters: %s\n", 
  strlen(szInLine), szInLine);
}

Approach 2:

while(ch = getc(stdin)) != EOF)
{

  if((*szInLine++ = ch) == '\n')
  {
    break; 
  } 
}
*szInLine = '\0';

fprintf(stdout, "Encrypted data string contains %i characters: %s\n", strlen(szInLine), szInLine);

Output for both cases : "Encrypted data string contains 256 characters: abcde.....

Other approaches I already tried but didn't succeed include changing the data type of the buffer which holds the value (from string to unsigned long), dynamically allocating memory to the buffer, setting stdin as unbuffered e.t.c.

OS environment : SCO Unix, 32bit Compiler: CC

2

There are 2 best solutions below

0
On

well, your programs (both) have errors:

/* you should include <stdio.h> so fgets() can return a char *,
 * If you don't, it's assumed fgets() returns an int value. */
#include <stdio.h>

main()
{
  char szInLine[999]; 
  memset(szInLine, 0, sizeof(szInLine)); /* you don't need this */

  fprintf(stdout, "\nPlease enter the encrypted value:\n");

  /* fgets accepts a buffer and its size, it will reserve space for
   * one '\0' char. */
  if (fgets(szInLine, sizeof szInLine, stdin) == NULL) {
   /* it is good to print some diagnostic if you receive EOF */
   return(1);
  }

  fprintf(stdout, "Encrypted data string contains %i characters: %s\n", 
  strlen(szInLine), szInLine);

  /* you should return 0, here */
  return(0);
}

The second is even worse:

/* unbalanced parenthesis, you lack a parenthesis after 'while' keyword */
while(ch = getc(stdin)) != EOF)
{

  if((*szInLine++ = ch) == '\n')
  {
    break; 
  } 
}
*szInLine = '\0';

/* if you move the pointer 'szInLine' it will always be pointing to the end of
 * the string, so this printf will show 0 characters and an empty string, you
 * had better to save the pointer at the beginning, so you don't lose the
 * reference to the string beginning.
 */
fprintf(stdout, "Encrypted data string contains %i characters: %s\n", strlen(szInLine), szInLine);

This should work:

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

int main()
{
    char buffer_in[1000];
    char buffer_out[1000];

    while (fgets(buffer_in, sizeof buffer, stdin)) {
         /* you'll get a line of up to 'sizeof buffer_in - 1' chars with an
          * ending '\n' (or a truncated if the line has more than 'sizeof
          * buffer_in - 1' chars. Also, you'll have a '\n' at the end of the
          * buffer, if the line filled partially the buffer. */
         fprintf(stderr, 
                "String read (%d chars): %s", /* this is why I don't put a '\n' here */
                strlen(buffer_in), 
                buffer_in);
         /* encrypt(buffer_in, sizeof buffer_in, buffer_out, sizeof buffer_out); */
    }
    /* here you got EOF */
    return 0;
}

or if you want to use getc():

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

int main()
{
    /* it is very important that c be an int, see manual 
     * page of fgetc(), getch() or getchar() */
    int c;
    char buffer[1000], *p = buffer;

    /* we check for buffer length and for EOF.  As we are doing the hard
     * work ourselves, we have to check for 'sizeof buffer - 1' to allow
     * space for the '\0'. */
    while ((p < buffer + sizeof buffer - 1) && ((c = getchar()) != EOF)) {
        if (c == '\n') { /* A NEWLINE, act on buffer, and skip it. */
             *p = '\0'; /* end the string */
             printf("Read %d chars: %s\n", p - buffer, buffer);
             /* crypt it ... */
             /* ... */
             p = buffer; /* reset buffer */
             continue;
        }
        *p++ = c; /* add the character to the buffer */
    }
    /* here you got EOF */
    return 0;
}

One final note:

Don't post snippets of code, but complete examples, as it is very difficult to identify which errors are mistakes on copying the code here, or which are mistakes you have made in the original program.

0
On

See the ioctl() and stty() manual page on the SCO web site. You should be able to retrieve the difference in the settings by testing terminal vs. redirection.