C 读取浮点的最小缓冲区长度

C 读取浮点的最小缓冲区长度,c,buffer,fgets,C,Buffer,Fgets,我正在编写一个小的命令行程序,从stdin读取两个浮点、一个int和一个小字符串(最多4个字符)。我正试图找出应该创建并传递给FGET的缓冲区大小。我想我可以根据float和int的最大值中应该包含多少位数来计算,如下所示: #include <float.h> #include <limits.h> ... int fmax = log10(FLOAT_MAX) + 2; // Digits plus - and . int imax = log10(INT

我正在编写一个小的命令行程序,从stdin读取两个浮点、一个int和一个小字符串(最多4个字符)。我正试图找出应该创建并传递给FGET的缓冲区大小。我想我可以根据
float
int
的最大值中应该包含多少位数来计算,如下所示:

#include <float.h>
#include <limits.h>

...

int fmax = log10(FLOAT_MAX) + 2;     // Digits plus - and .
int imax = log10(INT_MAX) + 1;       // Digits plus -
int buflen = 4 + 2*fmax + imax + 4;  // 4 chars, 2 floats, 1 int, 3 spaces and \n

...

fgets(inbuf, buflen + 1, stdin);
#包括
#包括
...
int fmax=log10(浮点最大值)+2;//数字加-和。
int imax=log10(int_MAX)+1;//数字加-
int buflen=4+2*fmax+imax+4;//4个字符,2个浮点数,1个整数,3个空格和\n
...
fgets(inbuf、buflen+1、标准DIN);
但我突然想到,这可能实际上并不正确
imax
在我的系统中是10,这似乎有点低,而
fmax
如果是40。(我认为这有点高,因为更长的值可以用e表示。)


所以我的问题是:这是解决这个问题的最好方法吗?这有必要吗?比起分配256个缓冲区并假设它足够,它感觉更优雅。称之为骄傲;P.

在这种情况下,我实际上会使用

fscanf
,而不是先读取固定大小的缓冲区。如果需要确保不跳过换行符或其他有意义的空格,可以使用
fgetc
逐个字符处理,直到得到数字的开头,然后在调用
fscanf
之前
ungetc


如果你想偷懒,只需选择一个大数字,比如1000…

这种类型的东西,我实际上会使用
fscanf
,而不是先读取固定大小的缓冲区。如果需要确保不跳过换行符或其他有意义的空格,可以使用
fgetc
逐个字符处理,直到得到数字的开头,然后在调用
fscanf
之前
ungetc


如果你想偷懒,只需选择一个大数字,比如1000…

我相信有一个很好的方法可以通过算法确定浮点字符串的最大长度,但这有什么乐趣呢?让我们用暴力来解决它

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

int main(int, char **)
{
   float f;
   unsigned int i = -1;
   if (sizeof(f) != sizeof(i))
   {
      printf("Oops, wrong size!  Change i to a long or whatnot so the sizes match.\n");
      return 0;
   }
   printf("sizeof(float)=%li\n", sizeof(float));

   char maxBuf[256] = "";
   int maxChars = 0;
   while(i != 0)
   {
      char buf[256];
      memcpy(&f, &i, sizeof(f));
      sprintf(buf, "%f", f);
      if ((i%1000000)==0) printf("Calclating @ %u: buf=[%s] maxChars=%i (maxBuf=[%s])\n", i, buf, maxChars, maxBuf);
      int numChars = strlen(buf);
      if (numChars > maxChars)
      {
         maxChars = numChars;
         strcpy(maxBuf, buf);
      }
      i--;
   }
   printf("Max string length was [%s] at %i chars!\n", maxBuf, maxChars);
}
#包括
#包括
#包括
int main(int,char**)
{
浮动f;
无符号整数i=-1;
如果(sizeof(f)!=sizeof(i))
{
printf(“哎呀,大小不对!请将i更改为long或其他名称,以便大小匹配。\n”);
返回0;
}
printf(“sizeof(float)=%li\n”,sizeof(float));
char maxBuf[256]=“”;
int-maxChars=0;
而(i!=0)
{
char-buf[256];
memcpy(&f,&i,sizeof(f));
sprintf(buf,“%f”,f);
如果((i%1000000)==0)printf(“计算@%u:buf=[%s]maxChars=%i(maxBuf=[%s])\n”,i,buf,maxChars,maxBuf);
int numChars=strlen(buf);
如果(numChars>maxChars)
{
maxChars=numChars;
strcpy(maxBuf,buf);
}
我--;
}
printf(“最大字符串长度为[%s],在%i个字符!\n”,maxBuf,maxChars);
}

看起来答案可能是每个浮点数47个字符(至少在我的机器上是这样),但我不会让它运行到最后,所以可能会更多。

我确信有一种很好的方法可以通过算法确定浮点数字符串的最大长度,但这有什么乐趣呢?让我们用暴力来解决它

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

int main(int, char **)
{
   float f;
   unsigned int i = -1;
   if (sizeof(f) != sizeof(i))
   {
      printf("Oops, wrong size!  Change i to a long or whatnot so the sizes match.\n");
      return 0;
   }
   printf("sizeof(float)=%li\n", sizeof(float));

   char maxBuf[256] = "";
   int maxChars = 0;
   while(i != 0)
   {
      char buf[256];
      memcpy(&f, &i, sizeof(f));
      sprintf(buf, "%f", f);
      if ((i%1000000)==0) printf("Calclating @ %u: buf=[%s] maxChars=%i (maxBuf=[%s])\n", i, buf, maxChars, maxBuf);
      int numChars = strlen(buf);
      if (numChars > maxChars)
      {
         maxChars = numChars;
         strcpy(maxBuf, buf);
      }
      i--;
   }
   printf("Max string length was [%s] at %i chars!\n", maxBuf, maxChars);
}
#包括
#包括
#包括
int main(int,char**)
{
浮动f;
无符号整数i=-1;
如果(sizeof(f)!=sizeof(i))
{
printf(“哎呀,大小不对!请将i更改为long或其他名称,以便大小匹配。\n”);
返回0;
}
printf(“sizeof(float)=%li\n”,sizeof(float));
char maxBuf[256]=“”;
int-maxChars=0;
而(i!=0)
{
char-buf[256];
memcpy(&f,&i,sizeof(f));
sprintf(buf,“%f”,f);
如果((i%1000000)==0)printf(“计算@%u:buf=[%s]maxChars=%i(maxBuf=[%s])\n”,i,buf,maxChars,maxBuf);
int numChars=strlen(buf);
如果(numChars>maxChars)
{
maxChars=numChars;
strcpy(maxBuf,buf);
}
我--;
}
printf(“最大字符串长度为[%s],在%i个字符!\n”,maxBuf,maxChars);
}

看起来答案可能是每个浮点数47个字符(至少在我的机器上是这样),但我不会让它运行到结束,所以它可能会更多。

这是为以10为基数的浮点数定义的(
\include
std::numeric\u limits
的等效成员):

以10为基数的小数的最大精度为:

FLT_DIG // for float
DBL_DIG // for double
LDBL_DIG  // for long double
尽管它实际上取决于您定义的有效浮点数。你可以想象有人期待:

00000000000000000000000000000000000000000000000000.00000000000000000000

读入为零。

这是为以10为基数的浮点数(
\include
std::numeric\u limits
的等效成员)定义的:

以10为基数的小数的最大精度为:

FLT_DIG // for float
DBL_DIG // for double
LDBL_DIG  // for long double
尽管它实际上取决于您定义的有效浮点数。你可以想象有人期待:

00000000000000000000000000000000000000000000000000.00000000000000000000

读作零。

根据@MSN的答案,您无法真正知道缓冲区是否足够大

考虑:

const int size = 4096;
char buf[size] = "1.";
buf[size -1 ] = '\0';
for(int i = 2; i != size - 1; ++i)
    buf[i] = '0';
double val = atof(buf);
std::cout << buf << std::endl;
std::cout << val << std::endl;
const int size=4096;
字符buf[大小]=“1。”;
buf[size-1]='\0';
对于(int i=2;i!=size-1;++i)
buf[i]=“0”;
双val=atof(buf);

std::cout根据@MSN的答案,您无法真正知道您的缓冲区是否足够大

考虑:

const int size = 4096;
char buf[size] = "1.";
buf[size -1 ] = '\0';
for(int i = 2; i != size - 1; ++i)
    buf[i] = '0';
double val = atof(buf);
std::cout << buf << std::endl;
std::cout << val << std::endl;
const int size=4096;
字符buf[大小]=“1。”;
buf[size-1]='\0';
对于(int i=2;i!=size-1;++i)
buf[i]=“0”;
双val=atof(buf);

STD::当你问问题时,请选择C和C++之间。根据您使用的语言,答案会有所不同。另外:看看INT_MAX,它实际上只有10位数左右,以10为基数表示。然后想想双精度(64位,尾数53位),你可能会看到40位听起来差不多正确。如果1GB值10美元,每个字节值0.000001美分。如果最低工资为每人6美元