【问题标题】:Issues while getting user input in SCO Unix OS在 SCO Unix OS 中获取用户输入时的问题
【发布时间】:2018-06-09 02:13:45
【问题描述】:

我在尝试通过我的代码获取用户输入时遇到了一个奇怪的问题。我很确定问题不在于代码,而是与标准输入流 (stdin) 等操作系统有关,但由于我没有另一台具有类似操作系统设置的机器(因为几乎找不到现在是一台 SCO 机器),我希望有一些程序化的解决方法来解决这个问题。我的程序从以'\n' 终止的用户处读取字母数字字符流。

但无论我如何尝试通过不同的方式来实现这一点,它只接受最初的 256 个字符。最初我怀疑问题出在 fgets 函数上,但是当我尝试使用 fgets 从文件中读取相同的值时,它按预期工作。

方法一:

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);
}

方法二:

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);

两种情况的输出:“加密数据字符串包含 256 个字符:abcde.....

我已经尝试过但未成功的其他方法包括更改保存值的缓冲区的数据类型(从字符串到 unsigned long)、动态分配内存到缓冲区、将 stdin 设置为无缓冲等

操作系统环境: SCO Unix,32 位 编译器: 抄送

【问题讨论】:

  • 在将输入输入到程序时,您是否能够读取超过 256 个字符? (./a.out <input_file_name)
  • 如果它在您从文件重定向时有效,但在您从 tty 读取时无效,那么问题是您的 tty 仅向您的程序发送 256 个字符。它与标准输入无关。问题在于 tty,tty 与标准输入不同。别把两者混为一谈了。
  • 谢谢,William Pursell,这是 tty 的问题,当我重定向输入时它可以工作。
  • “方法 2”正在修改指向缓冲区的指针。更好地索引到缓冲区或声明第二个指针。

标签: c unix cc sco-unix


【解决方案1】:

请参阅 SCO 网站上的 ioctl() 和 stty() 手册页。您应该能够通过测试终端与重定向来检索设置中的差异。

【讨论】:

    【解决方案2】:

    好吧,你的程序(两个)都有错误:

    /* 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);
    }
    

    第二个更糟糕:

    /* 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);
    

    这应该可行:

    #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;
    }
    

    或者如果你想使用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;
    }
    

    最后一点:

    不要贴sn-ps的代码,而是完整的例子,因为很难确定哪些错误是在这里复制代码的错误,或者哪些是你在原始程序中犯的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-10
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多