【问题标题】:read length of string from stdin [duplicate]从标准输入读取字符串的长度 [重复]
【发布时间】:2011-02-25 10:58:15
【问题描述】:

我想从标准输入中获取一个字符串,但我不想要一个固定大小的静态数组

我知道 scanf 需要一些东西来保存标准输入,但我不能这样做:

char string[10]
scanf("%s",string);

因为我需要知道字符串要多长时间才能分配正确的内存空间。

你能帮我解决这个问题吗?


呜呜呜

我仍然被这个问题锁定...... 我要疯了

你能给我工作代码吗?

【问题讨论】:

    标签: c stdin


    【解决方案1】:

    唯一确定的方法是循环;一次读取一个字符并存储。如果您分配的缓冲区已满,请将其增大一些合适的量(建议一次超过一个字节以提高性能,经典的经验法则是将其加倍)。

    当您认为字符串结束时停止,可能在换行符或 EOF 处。

    【讨论】:

      【解决方案2】:

      您可以使用以下方法逐字符处理输入数据:

      int getc(FILE *stream);
      

      int getchar(void);
      

      【讨论】:

        【解决方案3】:

        您可以使用以下格式字符串:

        char string[10];
        scanf("%10s" string);
        

        这会强制遵守缓冲区边界,但要求格式字符串了解缓冲区的大小。我通常通过将两者都声明为常量来克服这个问题:

        #define BUFSIZE 10
        #define BUFFMT "%10s"
        

        如果您在 GNU 系统上工作,您还可以利用 GNU 扩展:getline(3) 函数可以避免很多麻烦!看看here

        【讨论】:

        • 该数组只能安全存储 9 个字符加上尾随的 NUL '\0'。
        • 正确,但是从stdin只读取了9个字符,所以没问题。
        【解决方案4】:

        您可以确保不会像这样过度运行缓冲区:

           char buffer[128];
           printf("Input Text: ");
           fgets(buffer,127,stdin);
        

        然后,如果您需要可变大小的输入,您只需保持相同的固定大小的输入量

        【讨论】:

          【解决方案5】:

          如果您不想要固定大小的静态数组,请考虑使用动态分配的数组,该数组会根据需要增长。

          如果您在 Linux 或其他支持 POSIX 2008 的系统上工作,那么您可以使用(较新的)getline() 函数。如果您无法访问此类功能,请考虑使用相同的界面滚动您自己的功能。

          【讨论】:

            【解决方案6】:

            不要使用scanf,使用fgets,这样可以防止读入太多字符。

            char tmp[256]={0x0};
            while(fgets(tmp, sizeof(tmp), stdin)!=NULL)
            {
                printf("%s", tmp);
            }
            

            fgets 将在行尾返回一个 '\n',当 stdin 关闭或遇到错误时返回 NULL。

            先玩它看看它的作用。如果您需要将输入行分解为字段,您可以在 tmp 上使用 sscanf(),sscanf 的工作方式与 scanf 类似,但在字符串上。

            【讨论】:

              【解决方案7】:

              如果您使用fgets(),那么如果缓冲区足够大,您很可能在缓冲区末尾有一个'\n' 字符。有些人可能希望通过strtok() 函数将其删除,但它是不安全的。

              我建议使用以下安全方法来删除该额外的特殊字符。

              char *get_line (char *s, size_t n, FILE *f)
              {
                char *p = fgets (s, n, f);
              
                if (p != NULL) strtok (s, "\n");
                return p;
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-11-01
                • 2015-10-11
                • 2012-04-02
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多