在C中将字符串转换为float(不含atof)

时间:2010-12-08 21:41:45

标签: c

我正在设计一个将字符串转换为float的函数。 例如“45.5”= 45.5

到目前为止,我有这个。但它似乎没有用。请记住,我们不能使用像atoi,atof甚至pow这样的任何C库函数。

int str2float( char *s )
{
    int num = 0;
    int dec = 0;
    double i = 1.0;
    int ten = 1;
    /***** ADD YOUR CODE HERE *****/

    for(; *s != '\0'; s++)
    {
        if (*s == '.'){
            for(; *s != '\0'; s++){
                dec = (dec * CONT) + (*s - '0');
                i++;
            }
        }else{
            num = (num * CONT) + (*s - '0');
        }

    }
    for(;i!=0;i--){
        ten *= 10;
    }
    dec = dec / (ten);
    printf("%d", dec);
    num += dec;
    return num;  
}

10 个答案:

答案 0 :(得分:15)

这是我的尝试:

float stof(const char* s){
  float rez = 0, fact = 1;
  if (*s == '-'){
    s++;
    fact = -1;
  };
  for (int point_seen = 0; *s; s++){
    if (*s == '.'){
      point_seen = 1; 
      continue;
    };
    int d = *s - '0';
    if (d >= 0 && d <= 9){
      if (point_seen) fact /= 10.0f;
      rez = rez * 10.0f + (float)d;
    };
  };
  return rez * fact;
};

答案 1 :(得分:2)

一个潜在的问题是,在检查它没有指向NULL终止符之前,s会被外部循环递增。

for(; *s != '\0'; s++)
{
        ...
        for(; *s != '\0'; s++){
        ...
        }
        // inner loop is done now since we have *s=='\0' ...
    ...
    // ... but now we're going to increment s again at the end of the outer loop!
}

在发现NULL终结符后,您需要立即退出内部和外部循环。

答案 2 :(得分:1)

这是我对atof功能的解决方案。

#include<stdio.h>
float my_a2f(char *);

main() {
  char ch[20];
  float i;
  printf("\n enter the number as a string\n");
  scanf("%[^\n]", ch);
  i = my_a2f(ch);
  printf(" string =%s , float =%g \n", ch, i);
}

float my_a2f(char *p) {
  // here i took another two   variables for counting the number of digits in mantissa
  int i, num = 0, num2 = 0, pnt_seen = 0, x = 0, y = 1; 
  float f1, f2, f3;
  for (i = 0; p[i]; i++)
    if (p[i] == '.') {
      pnt_seen = i;
      break;
    }
  for (i = 0; p[i]; i++) {
    if (i < pnt_seen) num = num * 10 + (p[i] - 48);
    else if (i == pnt_seen) continue;
    else {
      num2 = num2 * 10 + (p[i] - 48);
      ++x;
    }
  }
  // it takes 10 if it has 1 digit ,100 if it has 2 digits in mantissa
  for (i = 1; i <= x; i++) 
    y = y * 10;
  f2 = num2 / (float) y;
  f3 = num + f2;
  return f3;
}

答案 3 :(得分:0)

这样的事情应该这样做:

float str2float(char* s){
// solve for special cases where s begins with 0's or nun numeric values, or if s is NULL
  float result = 0;
  int decimalCount = 0, i = 0, decimalPointLoc = strlen(s);
  for (; s[i] != '\0'; i++){
    if (s[i] == '.') decimalPointLoc = i;
    if (i < decimalPointLoc) { result *= 10; result += (int)(s[i] + '0'); }
    else { result += (float)(s[i] + '0')/(pow(i-decimalPointLoc,10)); }
  }
  return result;
}

代码可能不是很干净,不一定是最好的方法,但你明白了。 pow(x,y)返回x ^ y并且需要math.h和strlen(s)返回s的大小并且需要string.h。

答案 4 :(得分:0)

double Myatof(char str[]){

int len=0, n=0,i=0;
float f=1.0,val=0.0;

//counting length of String
while(str[len])len++;
//cheking for valid string
if(!len)return 0;

//Extracting Integer  part
while(i<len && str[i]!='.')
    n=10*n +(str[i++]-'0');

//checking if only Integer 
if(i==len) return n;
i++;
while(i<len)
{
    f*=0.1;
    val+=f*(str[i++]-'0');
    }
    return(val+n);
}

答案 5 :(得分:0)

#define ZERO 48
#define NINE 57
#define MINUS 45
#define DECPNT 46

int strtoint_n(char* str, int n)
{
    int sign = 1;
    int place = 1;
    int ret = 0;

    int i;
    for (i = n-1; i >= 0; i--, place *= 10)
    {
        int c = str[i];
        switch (c)
        {
            case MINUS:
                if (i == 0) sign = -1;
                else return -1;
                break;
            default:
                if (c >= ZERO && c <= NINE) ret += (c - ZERO) * place;
                else return -1;
        }
    }

    return sign * ret;
}

float _float_fraction(char* str, int n)
{
    float place = 0.1f;
    float ret = 0.0f;

    int i;
    for (i = 0; i < n; i++, place /= 10)
    {
        int c = str[i];
        ret += (c - ZERO) * place;
    }
    return ret;
}
float strtoflt(char* str)
{
    int n = 0;
    int sign = 1;
    int d = -1;
    int ret = 0;

    char* temp = str;
    while (*temp != '\0')
    {
        switch (*temp)
        {
            case MINUS:
                if (n == 0) sign = -1;
                else return -1;
                break;
            case DECPNT:
                if (d == -1) d = n;
                else return -1;
                break;
            default:
                if (*temp < ZERO && *temp > NINE) return -1;
        }
        n++;
        temp++;
    }

    if (d == -1)
    {
        return (float)(strtoint_n(str, n));
    }
    else if (d == 0)
    {
        return _float_fraction((str+d+1), (n-d-1));
    }
    else if (sign == -1 && d == 1)
    {
        return (-1)*_float_fraction((str+d+1), (n-d-1));
    }
    else if (sign == -1)
    {
        ret = strtoint_n(str+1, d-1);
        return (-1) * (ret + _float_fraction((str+d+1), (n-d-1)));
    }
    else
    {
        ret = strtoint_n(str, d);
        return ret + _float_fraction((str+d+1), (n-d-1));
    }
}

答案 6 :(得分:0)

#include<stdio.h>
#include<string.h>
float myAtoF(char *);
//int myAtoI(char);
void main(int argc,char **argv)
{
float res;
char str[10];
if(argc<2)
{
    printf("Supply a floating point Data\n");
    return;
}
printf("argv[1] = %s\n",argv[1]);
//  strcpy(str,argv[1]);
//  printf("str = %s\n",str);
    res=myAtoF(argv[1]);
    printf("Res = %f\n",res);
   }
float myAtoF(char *str)
{
    printf("str = %s\n",str);
    int i,sum,total,index;
    float res;
    if(!strchr(str,'.'))
    {
        printf("Supply only real Data\n");
        return ;
    }
    i=0;
    while(str[i])
    {
        if(!str[i]>='0'&&str[i]<='9')
        {
            printf("Wrong Data Supplied\n");
            return;    

        }
        if(str[i]=='.')
        { 
            index=i;
            i++;
            continue;

        }
        total=str[i]-48;
        if(i==0)
        {
            sum=total;
            i++;
            continue;
        }
        sum=sum*10+total;
        i++;
    }
    printf("Integer Data : %d\n",sum);
    index=(strlen(str)-1)-index;
    printf("index : %d\n",index);
    res=sum;
    for(i=1;i<=index;i++)
    {
        res=(float)res/10;
    }
    return res;
}

答案 7 :(得分:0)

double atof(char* num)
 {
     if (!num || !*num)
         return 0; 
     double integerPart = 0;
     double fractionPart = 0;
     int divisorForFraction = 1;
     int sign = 1;
     bool inFraction = false;
     /*Take care of +/- sign*/
     if (*num == '-')
     {
         ++num;
         sign = -1;
     }
     else if (*num == '+')
     {
         ++num;
     }
     while (*num != '\0')
     {
         if (*num >= '0' && *num <= '9')
         {
             if (inFraction)
             {
                 /*See how are we converting a character to integer*/
                 fractionPart = fractionPart*10 + (*num - '0');
                 divisorForFraction *= 10;
             }
             else
             {
                 integerPart = integerPart*10 + (*num - '0');
             }
         }
         else if (*num == '.')
         {
             if (inFraction)
                 return sign * (integerPart + fractionPart/divisorForFraction);
             else
                 inFraction = true;
         }
         else
         {
             return sign * (integerPart + fractionPart/divisorForFraction);
         }
         ++num;
     }
     return sign * (integerPart + fractionPart/divisorForFraction);
 }

答案 8 :(得分:0)

我的解决方案:

emp_name, count(*)
abc, 4
def, 2
xyz, 10

测试

float str2float (const char * str) {
  unsigned char abc;
  float ret = 0, fac = 1;
  for (abc = 9; abc & 1; str++) {
    abc  =  *str == '-' ?
              (abc & 6 ? abc & 14 : (abc & 47) | 36)
            : *str == '+' ?
              (abc & 6 ? abc & 14 : (abc & 15) | 4)
            : *str > 47 && *str < 58 ?
              abc | 18
            : (abc & 8) && *str == '.' ?
              (abc & 39) | 2
            : !(abc & 2) && (*str == ' ' || *str == '\t') ?
              (abc & 47) | 1
            :
              abc & 46;
    if (abc & 16) {
      ret = abc & 8 ? *str - 48 + ret * 10 : (*str - 48) / (fac *= 10) + ret;
    }
  }
  return abc & 32 ? -ret : ret;
}

顺便说一句,如果有人需要它,这里也是我将字符串转换为整数的解决方案:

printf("%f\n", str2float("234.3432435543")); // 234.343246
printf("%f\n", str2float("+234.3432435543")); // 234.343246
printf("%f\n", str2float("-234.3432435543")); // -234.343246
printf("%f\n", str2float("   +  234.3432435543")); // 234.343246
printf("%f\n", str2float(".5")); // 0.500000
printf("%f\n", str2float("- .5")); // -0.500000

答案 9 :(得分:-1)

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


double myatof(char *num);
int main(void)
{
    double res;char str[15];

    printf("enter a number in the form of a  string:\n");
    gets(str);
    res=myatof(str);
    printf("Float representation of above number  is %f\n",res);
    return 0;
}

double myatof(char *str)
{
    int i=0;int len1,len2,j;
    float num=0.0;float num1=0.0; float num2=0.0;

    do
    {
        if((str[i++]=='.'))
        {
            len1=i-1;len2=-((strlen(str)-1)-(i-1));

            for(int p=0,q=(len1-1);p<len1,q>=0;p++,q--)
            {
                num1+=((str[p]-'0')*pow(10,q));
            }
            for(int r=len1+1,s=-1;r<strlen(str),s>=len2;r++,s--)
            {
                num2+=((str[r]-'0')*pow(10,s));
            }
        }
    }while(str[i]!='\0');

    num=num1+num2;
    printf("%f\t",num1);
    printf("%f\t",num2);
    return num;
}