2016-04-09 3 views
1

Мне нужно прочитать значение (cin), включая знак доллара и сумму в долларах, но я хочу только прочитать сумму.Читать в Долларе Сумма (со знаком доллара) C++

Другими словами, у меня есть этот вход: «$ 3458,5,» , но я хочу, чтобы читать и хранить «3458,5»

Нынешний подход, я думал о зачитывал значение в виде строки, удаление первого символа, а затем преобразование в двойное. Но я чувствую, что этот метод неэффективен, и там есть лучший метод. Какие-нибудь советы? Благодаря!

+7

Это звучит как небольшая неэффективность, о которой вы не должны беспокоиться :) –

+1

Я стараюсь держаться подальше от языка C++, потому что я нахожу его слишком сложным и навязчивым и даже не переносным из-за отсутствия поддержки реализации, но там * это * ['std :: money_get'] (http://en.cppreference.com/w/cpp/locale/money_get) и связанное с ним оборудование. Насколько я помню, П.Я.Плаугер написал серию статей о том, как ее использовать. Возможно, стоит поиграть в игру - или нет, IDK. Примером непереносимости является использование языкового стандарта UTF-8 в примере кода для документов, с которыми я связан, на cppreference.com. Это не сработает с Visual C++, где документировано, что локали UTF-8 не поддерживаются. –

+0

В стороне: переменные с плавающей запятой и валюта не очень хорошо сочетаются. – edmz

ответ

4

Я согласен с Магнусом: это кажется незначительным. Но если вы действительно хотите сделать это, только что прочитал символ затем прочитал дважды:

char ch; 
double d; 
std::cin >> ch >> d; 
+0

Я думал об этом, но я подумал, что он попытается прочитать всю строку как символ, который сделает его недействительным. Не имеет значения, что между $ и суммой нет пробелов? – Sam

+1

Nevermind, я только что протестировал его, спасибо! – Sam

2
if(stream.peek() == '$') stream.get(); 
stream >> amount; 
+0

Мне, вероятно, не нужна проверка, так как ввод обещаний будет хорошо отформатирован, но это сработает, спасибо! – Sam

+0

хороший ответ. Если вы также делаете ** if (stream.peek() == '$') ** на ** в то время как (stream.peek() == '$') **, он будет обеспечивать отказ от любого числа ' $ 'из потока перед чтением номера. –

+0

Давайте сделаем это настоящим! 'for (char c = stream.peek();! (c == '-' || c == '.' || std :: isdigit (c)); c = stream.peek()) stream.get(); ' – bipll

1

Если вы используете scanf вместо cin, вы можете отказаться от $, если вы знаете, что это всегда будет там и пишите информацию непосредственно в поплавок.

float d; 
scanf("$%f", d); 
+0

Это тоже работает, спасибо! – Sam

1

C++ 98/03 была money_get огранку, чтобы делать такие вещи. К сожалению, использование этого было довольно болезненным (чтобы это было приятно).

C++ 11 добавлен манипулятор get_money, чтобы сделать жизнь немного проще. Он работает примерно так:

#include <iostream> 
#include <iomanip> 

int main() { 
    long double amt; 

    std::cin.imbue(std::locale("")); 
    std::cout.imbue(std::locale("")); 

    std::cin >> std::get_money(amt); 
    std::cout << std::showbase << std::put_money(amt) << "\n"; 
} 

Теперь, здесь есть пара вещей. Прежде всего, преобразование из внешнего в внутреннее представление не указано, но в реализациях, которые я видел, $3458.5 будет не быть прочитанным как 3458.5 - он должен быть прочитан и сохранен как 345850 - то есть , подсчет количества копеек.

Если вы используете put_money для записи данных, то он будет преобразован симметрично с тем, что было сделано во время ввода, поэтому, если вы ввели $3458.5, он будет записан обратно таким же образом.

Существует еще один нюанс: я видел, по крайней мере, одна реализации, которая была странно привередливо о формате ввод, поэтому требуется либо 0, либо 2 цифры после десятичной точки во время ввода, так как $3458.50 или $3458 будет читать хорошо, но $3458.5 не будет читаться вообще (это будет рассматриваться как неудачное преобразование).

+0

Gotcha, я думаю, что я буду придерживаться одного из первых решений пары, но хорошо знать, что это такое! Благодаря! – Sam