Форум программистов, компьютерный форум CyberForum.ru

Преобразование типов string->double c заданной точностью*? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 52, средняя оценка - 4.65
Antka
Сообщений: n/a
07.08.2012, 20:34     Преобразование типов string->double c заданной точностью*? #1
Есть входящая строка 123456 или 00546.. или любая другая.

Как преобразовать в тип double, чтобы на выходе я получил:
123.456
0.546

Язык с++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Catstail
Модератор
 Аватар для Catstail
21436 / 10221 / 1666
Регистрация: 12.02.2012
Сообщений: 17,096
07.08.2012, 20:56     Преобразование типов string->double c заданной точностью*? #2
Самое простое - воспользоваться функцией atof:

C++
1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
#include <iostream.h>
 
int main(int argc, char* argv[])
{
 
    char *S = "123.456";
    cout << atof(S) << endl;
    return 0;
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
07.08.2012, 20:57     Преобразование типов string->double c заданной точностью*? #3
Catstail, В С++-то... Агась. stringstream конечно куда тяжелее. Ну и если на то пошло const char*, а не просто char*.

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <sstream>
#include <string>
 
int main()
{
    std::string s = "123.456";
    double d = 0.0;
    std::stringstream ss(s);
    ss >> d;
    std::cout << d << std::endl;
}
Catstail
Модератор
 Аватар для Catstail
21436 / 10221 / 1666
Регистрация: 12.02.2012
Сообщений: 17,096
07.08.2012, 21:12     Преобразование типов string->double c заданной точностью*? #4
А что, atof в C++ не поддерживается? Вообще-то, методический смысл от того, чтобы вспомнить, какую функцию вызвать - невелик... Для пытливых умов приведу код перевода:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdlib.h>
#include <iostream.h>
#include <string.h>
 
double char2double(char *S)
{
    int i,l,k=1;
    double r=0,p=1;
    for (i=0; i< strlen(S); i++)
    {
        if (k < 0) p=p*10;
        if (S[i] == '.')
            k=-k;
        else
            r=r*10+(S[i]-'0');
    }
    return r/p;
}
 
int main(int argc, char* argv[])
{
 
    char *S = "123.456";
    cout << atof(S) << endl;
    cout << char2double(S) << endl;
    return 0;
}
Функция char2double переводит в double строки вида "nnnn.mmmm". Доработать эту функцию, чтобы она брала строки вида "+/- nnn.mmmE+/-pp" оставляю ТС в качестве полезного упражнения (которое каждый программист должен один раз выполнить сам)
Antka
Сообщений: n/a
07.08.2012, 22:46     Преобразование типов string->double c заданной точностью*? #5
Проблема стандартной функции atof (и других) то, что она отваливается (return 0.0) если туда передать строку такого вида
"00.333"
zitxbit
Master C/C++
 Аватар для zitxbit
86 / 738 / 75
Регистрация: 11.04.2012
Сообщений: 971
08.08.2012, 08:16     Преобразование типов string->double c заданной точностью*? #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
 
double str2f(char* str, int ps)
{
    char* sw = strchr(str,'.');
    if (sw != NULL) while (*sw != '\0') *sw++ = *(sw+1);
 
    int n = strlen(str)-1;
    int len = strlen(str)-ps >= 0 ? strlen(str)-ps : 0;
    while (n >= len && sw != NULL) 
        str[n+1] = str[n--]; str[n+1] = '.';
 
    if (str[strlen(str)-1] == '.')
    {
        str[strlen(str)+1] = str[strlen(str)];
        str[strlen(str)] = '0';
    }
 
    else if (str[0] == '.')
    {
        for (int q = strlen(str)-1; q >= 0; q--)
            str[q+1] = str[q]; str[0] = '0';
    }
 
    int r = ps;
    double dd = 0; bool b = false;
    for (int n = strlen(str)-1; n >= 0; n--)
    {
        if (str[n] == '.') { r = 0; n--; b = true; }
        if (b) dd+=(str[n] - '0') * pow(10.,r++);
        else { dd+=(str[n] - '0') * pow(10.,-r); r--; }
    }
 
    return dd;
}
 
int main()
{
    static char str[256] = "126.24";
    printf("double = %f precision = 4\n",str2f(str,4));
 
    _getch();
 
    return 0;
}
http://liveworkspace.org/code/5f851f...f2bfaddee93262
Catstail
Модератор
 Аватар для Catstail
21436 / 10221 / 1666
Регистрация: 12.02.2012
Сообщений: 17,096
08.08.2012, 09:15     Преобразование типов string->double c заданной точностью*? #7
Цитата Сообщение от Antka Посмотреть сообщение
Проблема стандартной функции atof (и других) то, что она отваливается (return 0.0) если туда передать строку такого вида
"00.333"
- гм... Вот мой код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdlib.h>
#include <iostream.h>
#include <string.h>
 
double char2double(char *S)
{
    int i,l=strlen(S),k=1;
    double r=0,p=1;
    for (i=0; i< l; i++)
    {
        if (k < 0) p=p*10;
        if (S[i] == '.')
            k=-k;
        else
            r=r*10+(S[i]-'0');
    }
    return r/p;
}
 
int main(int argc, char* argv[])
{
    char *S = "00123.456"; // нарочно набил незначащих нулей!
    cout << atof(S) << endl;
    cout << char2double(S) << endl;
    return 0;
}
А вот результат (см. миниатюру). atof работает совершенно нормально! (VC++ 6.0)
Миниатюры
Преобразование типов string->double c заданной точностью*?  
-=ЮрА=-
Заблокирован
Автор FAQ
08.08.2012, 09:33     Преобразование типов string->double c заданной точностью*? #8
Цитата Сообщение от Antka Посмотреть сообщение
Есть входящая строка 123456 или 00546.. или любая другая.
Как преобразовать в тип double, чтобы на выходе я получил:
123.456
0.546
Язык с++
- можно воспользоваться возможностями sscanf
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <string>
#include <iostream>
using namespace std;
 
int main()
{
    string str = "12.56 14";
    int    iParam = 0;
    double dParam = 0;
    //2 - îçГ*Г*Г·Г*ГҐГІ ÷èñëî Г±Г·ГЁГІГ*Г*Г*ûõ ГЇГ*Г°Г*ìåòðîâ
    if(sscanf(str.c_str(),"%lf %d",&dParam,&iParam) != 2)
        cout<<"Error parsing params from string\n";
    else
        cout<<"int    : "<<iParam<<endl
            <<"double : "<<dParam<<endl;
    return 0;
}
http://codepad.org/9hdpx1Kn

Не по теме:

PS:ForEveR, реально хватит кичиться тем что хорошо знаем STL и некоторые примочки плюсов - это не удел знающего человека, а скорее пацана!
Тогда я скажу - "конечно а sscanf куда сложней чем stringstream"

Миниатюры
Преобразование типов string->double c заданной точностью*?  
-=ЮрА=-
Заблокирован
Автор FAQ
08.08.2012, 09:36     Преобразование типов string->double c заданной точностью*? #9
Цитата Сообщение от Antka Посмотреть сообщение
Проблема стандартной функции atof (и других) то, что она отваливается (return 0.0) если туда передать строку такого вида
"00.333"
- а ты sscanf попробуй

Добавлено через 48 секунд
http://liveworkspace.org/code/48880a...badd0a7c6f8107
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
08.08.2012, 09:57     Преобразование типов string->double c заданной точностью*? #10
-=ЮрА=-, Мммм. Предпочитаю в С++ использовать функции С++, а не С и остальным того же советую, как минимум потому, что они типобезопасны (чего не сказать о sscanf, atof и прочих сишных функциях). В частности на тему atof:

If no valid conversion could be performed, the function returns zero (0.0).
There is no standard specification on what happens when the converted value would be out of the range of representable values by a double.
То есть как минимум лучше юзать strtod который хоть errno выставляет.

C++
1
2
3
4
5
6
7
8
#include <string>
#include <iostream>
 
int main()
{
   std::string s = "00123.456";
   std::cout << std::stod(s) << std::endl;
}
http://liveworkspace.org/code/1ab726...951980f9432a45
-=ЮрА=-
08.08.2012, 11:13
  #11

Не по теме:

ForEveR, sscanf выбрасывает EOF в случае ошибки:

On success, the function returns the number of variables filled. This count can match the expected number of readings or fewer, even zero, if a matching failure happens.
In the case of an input failure before any data could be successfully read, EOF is returned.
http://www.cplusplus.com/reference/c...cstdio/sscanf/
На счёт плюсов и сей: функция sscanf включена в cstdio, следовательно её можно использовать на усмотрение разработчика (или приемственность плюсов по отношению коду сей это ненужная фича по твоему?)

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.08.2012, 11:21     Преобразование типов string->double c заданной точностью*?
Еще ссылки по теме:

Преобразование string в long double C++
C++ Преобразование типов. Откуда берётся double?
Преобразование типов double в int для задания размерности массива C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
08.08.2012, 11:21     Преобразование типов string->double c заданной точностью*?
  #12

Не по теме:

-=ЮрА=-, Нужная конечно. Когда нужно быстродействие (и то если профайлер показал, что действительно тормоза именно в этом, иначе это экономия на спичках), а в остальных случаях лучше использовать С++-функции.

Yandex
Объявления
08.08.2012, 11:21     Преобразование типов string->double c заданной точностью*?
Ответ Создать тему
Опции темы

Текущее время: 04:35. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru