Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C中的字符串分析浮点值时出现问题_C - Fatal编程技术网

从C中的字符串分析浮点值时出现问题

从C中的字符串分析浮点值时出现问题,c,C,假设有一个字符串我想在C中解析。 对于解析,我想使用函数sscanf() 现在,在字符串中有一个浮点型数字,它可以扩展到一个较大的值(在十进制之前/之后),有时甚至更小。基本上,这意味着数字的宽度是可变的 比如说, 号码可以是15.5686、15.5686778887或156.867788 让我们用这样的字符串 Str1 = "Hello15.5686World" Str1 = "Hello15.5686778887World" 在运行时,可能必须解析上述任何字符串 然而,这个数字的起点是固定

假设有一个字符串我想在C中解析。 对于解析,我想使用函数
sscanf()

现在,在字符串中有一个浮点型数字,它可以扩展到一个较大的值(在十进制之前/之后),有时甚至更小。基本上,这意味着数字的宽度是可变的

比如说,

号码可以是15.5686、15.5686778887或156.867788

让我们用这样的字符串

Str1 = "Hello15.5686World"
Str1 = "Hello15.5686778887World"
在运行时,可能必须解析上述任何字符串


然而,这个数字的起点是固定的,但我们不知道它在哪里结束。那么,确定相同值的方法是什么,以便可以正确解析或读取“World”(数字后的子字符串)。

您可以使用
strod
函数族来解析字符串。您可以将指向字符的指针传递给
strtod
,解析数字后,该指针将指向字符串的其余部分:

const char *Str1 = "Hello15.5686World", *endptr;
double num = strtod(Str1 + strlen("Hello"), &endptr);

printf("number: %f, rest of string: %s\n", num, endptr);

这将使用strpbrk查找字符串中的小数。
no
指针向字符串开头迭代,以查找小数点前面的数字。如果小数点前面的所有字符都是数字,则前四个字符假定为前导字符串。
s
指针向字符串末尾迭代,以查找小数点后的数字。如果小数点后的所有字符都是数字,则最后六个字符假定为尾随字符串

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

int main( void)
{
    //char str[] = { "abc123def98.76543zyc098"};
    char str[] = { "123498.76543123456"};
    char *leading = NULL;
    char *trailing = NULL;
    char *no = NULL;
    char *s = NULL;
    char *decimal = NULL;
    double value;

    if ( ( decimal = strpbrk ( str, ".")) != NULL) {//find the decimal
        s = decimal;//for trailing string
        no = decimal;//for start of numeric value
        while ( no > str) {//stop at start of str
            no--;//iterate toward start
            if ( !isdigit ( *no)) {
                no++;
                break;
            }
        }
        while ( *s) {//stop at '\0'
            s++;//iterate toward end of str
            if ( !isdigit ( *s)) {
                break;
            }
        }
        if ( no == str) {//all digits
            no = str + 4;//first four characters will belong to leading
            if ( no >= decimal) {
                printf ( "problem with leading string\n");
                exit ( 1);
            }
        }
        if ( *s == '\0') {//all digits
            s = s - 6;//last six characters will belong to trailing
            if ( s <= decimal) {
                printf ( "problem with trailing string\n");
                exit ( 1);
            }
        }

        if ( ( trailing = malloc ( strlen ( s) + 1)) == NULL) {
            printf ( "malloc problem\n");
            exit ( 1);
        }

        if ( ( leading = malloc ( ( no - str) + 1)) == NULL) {
            free ( trailing);
            printf ( "malloc problem\n");
            exit ( 1);
        }

        memcpy ( trailing, s, strlen ( s));
        trailing[strlen ( s)] = '\0';

        memcpy ( leading, str, no - str);
        leading[no - str] = '\0';

        *s = '\0';//for the next sscanf terminate no at s

        if ( ( sscanf ( no, "%lf", &value)) != 1) {
            free ( leading);
            free ( trailing);
            printf ( "sscanf problem\n");
            exit ( 1);
        }


        printf ( "leading %s\n", leading);
        printf ( "value %f\n", value);
        printf ( "trailing %s\n", trailing);


    }
    else {
        printf ( "no decimal found\n");
    }

    free ( leading);
    free ( trailing);

    return 0;
}
#包括
#包括
#包括
#包括
内部主(空)
{
//char str[]={“abc123def98.76543zyc098”};
char str[]={“123498.76543123456”};
字符*前导=空;
char*training=NULL;
char*no=NULL;
char*s=NULL;
char*decimal=NULL;
双重价值;
如果((decimal=strpbrk(str,“.”)!=NULL){//查找小数点
s=decimal;//用于尾随字符串
否=十进制;//用于数字值的开头
而(no>str){//str开始时停止
否--;//向开始迭代
如果(!isdigit(*否)){
否++;
打破
}
}
而(*s){//在'\0'处停止
s++;//在str的末尾迭代
如果(!isdigit(*s)){
打破
}
}
如果(no==str){//所有数字
no=str+4;//前四个字符将属于前导字符
如果(否>=十进制){
printf(“前导字符串问题”);
出口(1);
}
}
如果(*s=='\0'){//所有数字
s=s-6;//最后六个字符将属于尾随字符

如果(s),则必须缩小可能的输入范围。1)数字可以是什么样的浮点格式?它是十进制的还是十六进制的?2)字符串的非数字部分可以包含数字吗?如果我们知道数字可以跨越的最大宽度,那么我们就可以确定它的起点/终点。但是,每次解析字符串时,不管字符串有多大或多小,这都会占用大量的空间数字是。@EOF:是的,非数字部分可能包含数字。在这种情况下,您的问题是定义不清的。它是否包含在您想要的数字和非数字部分中的随机数字之间没有任何其他字符的数字?考虑到OP说非数字部分可以包含数字,序列
“H0xello15.5686World”
可能不会返回OP期望的值。而且,
strtod()
在这种情况下将失败,因为
'H'
既不是空格,也不是十六进制/十进制字符。@EOF OP说:“数字的起点是固定的,但我们不知道它在哪里结束。”因此,只需将数字的开头传递给
strtol
@BLUEPIXY即可。谢谢。到目前为止,它一直按照我的要求工作。我将继续尝试不同的输入。非常感谢。