这是我的代码:
didTapConvertButton(_:)
我希望输出应为:
JSONDecoder
但是实际结果是:
// CurrencyViewController.swift
import UIKit
import Alamofire
// types used by this view controller
struct Currency {
let code: String // standard three character code
let localeIdentifier: String // a `Locale` identifier string used to determine how to format the results
}
enum CurrencyExchangeError: Error {
case currencyNotSupplied
case valueNotSupplied
case currencyNotFound
case webServiceError(String)
case unknownNetworkError(Data?, HTTPURLResponse?)
}
struct ExchangeRateResponse: Codable {
let error: String?
let base: String?
let rates: [String: Double]?
}
class CurrencyExchangeViewController: UIViewController {
// outlets
@IBOutlet weak var inputTextField: UITextField!
@IBOutlet weak var inputCurrencySegmentedControl: UISegmentedControl!
@IBOutlet weak var outputCurrencySegmentedControl: UISegmentedControl!
@IBOutlet weak var resultLabel: UILabel!
// private properties
private let currencies = [
Currency(code: "EUR", localeIdentifier: "fr_FR"),
Currency(code: "JPY", localeIdentifier: "jp_JP"),
Currency(code: "CNY", localeIdentifier: "ch_CH"),
Currency(code: "USD", localeIdentifier: "en_US")
]
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.isNavigationBarHidden = true
updateCurrencyControls()
}
@IBAction func didTapConvertButton(_ sender: Any) {
let inputIndex = inputCurrencySegmentedControl.selectedSegmentIndex
let outputIndex = outputCurrencySegmentedControl.selectedSegmentIndex
guard inputIndex >= 0, outputIndex >= 0 else {
resultLabel.text = errorMessage(for: CurrencyExchangeError.currencyNotSupplied)
return
}
guard let text = inputTextField.text, let value = Double(text) else {
resultLabel.text = errorMessage(for: CurrencyExchangeError.valueNotSupplied)
return
}
performConversion(from: inputIndex, to: outputIndex, of: value) { result in
switch result {
case .failure(let error):
self.resultLabel.text = self.errorMessage(for: error)
case .success(let string):
self.resultLabel.text = string
}
}
}
func updateCurrencyControls() {
outputCurrencySegmentedControl.removeAllSegments()
inputCurrencySegmentedControl.removeAllSegments()
enumerateCurrencies { index, code in
outputCurrencySegmentedControl.insertSegment(withTitle: code, at: index, animated: false)
inputCurrencySegmentedControl.insertSegment(withTitle: code, at: index, animated: false)
}
}
}
// these might better belong in a presenter or view model rather than the view controller
private extension CurrencyExchangeViewController {
func enumerateCurrencies(block: (Int, String) -> Void) {
for (index, currency) in currencies.enumerated() {
block(index, currency.code)
}
}
func errorMessage(for error: Error) -> String {
switch error {
case CurrencyExchangeError.currencyNotFound:
return NSLocalizedString("No exchange rate found for those currencies.", comment: "Error")
case CurrencyExchangeError.unknownNetworkError:
return NSLocalizedString("Unknown error occurred.", comment: "Error")
case CurrencyExchangeError.currencyNotSupplied:
return NSLocalizedString("You must indicate the desired currencies.", comment: "Error")
case CurrencyExchangeError.valueNotSupplied:
return NSLocalizedString("No value to convert has been supplied.", comment: "Error")
case CurrencyExchangeError.webServiceError(let message):
return NSLocalizedString(message, comment: "Error")
case let error as NSError where error.domain == NSURLErrorDomain:
return NSLocalizedString("There was a network error.", comment: "Error")
case is DecodingError:
return NSLocalizedString("There was a problem parsing the server response.", comment: "Error")
default:
return error.localizedDescription
}
}
func performConversion(from fromIndex: Int, to toIndex: Int, of value: Double, completion: @escaping (Result<String?>) -> Void) {
let originalCurrency = currencies[fromIndex]
let outputCurrency = currencies[toIndex]
fetchExchangeRates(for: originalCurrency.code) { result in
switch result {
case .failure(let error):
completion(.failure(error))
case .success(let exchangeRates):
guard let exchangeRate = exchangeRates.rates?[outputCurrency.code] else {
completion(.failure(CurrencyExchangeError.currencyNotFound))
return
}
let outputValue = value * exchangeRate
let locale = Locale(identifier: outputCurrency.localeIdentifier)
let string = formatter(for: locale).string(for: outputValue)
completion(.success(string))
}
}
/// Currency formatter for specified locale.
///
/// Note, this formats number using the current locale (e.g. still uses
/// your local grouping and decimal separator), but gets the appropriate
/// properties for the target locale's currency, namely:
///
/// - the currency symbol, and
/// - the number of decimal places.
///
/// - Parameter locale: The `Locale` from which we'll use to get the currency-specific properties.
/// - Returns: A `NumberFormatter` that melds the current device's number formatting and
/// the specified locale's currency formatting.
func formatter(for locale: Locale) -> NumberFormatter {
let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = locale
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencyCode = currencyFormatter.currencyCode
formatter.currencySymbol = currencyFormatter.currencySymbol
formatter.internationalCurrencySymbol = currencyFormatter.internationalCurrencySymbol
formatter.maximumFractionDigits = currencyFormatter.maximumFractionDigits
formatter.minimumFractionDigits = currencyFormatter.minimumFractionDigits
return formatter
}
}
}
// this might better belong in a network service rather than in the view controller
private extension CurrencyExchangeViewController {
func fetchExchangeRates(for inputCurrencyCode: String, completion: @escaping (Result<ExchangeRateResponse>) -> Void) {
Alamofire.request("https://api.exchangeratesapi.io/latest?base=\(inputCurrencyCode)").response { response in
guard response.error == nil, let data = response.data else {
completion(.failure(response.error ?? CurrencyExchangeError.unknownNetworkError(response.data, response.response)))
return
}
do {
let exchangeRates = try JSONDecoder().decode(ExchangeRateResponse.self, from: data)
if let error = exchangeRates.error {
completion(.failure(CurrencyExchangeError.webServiceError(error)))
} else {
completion(.success(exchangeRates))
}
} catch {
completion(.failure(error))
}
}
}
}
答案 0 :(得分:1)
我认为您之前输入的“预期输出”是错误的(我认为应该是186 240 294 348 402 456 510 564 618 672
),并且您有不必要的循环和额外的索引变量。再检查一遍。这是我认为您想做的事情的方法:
int main() {
int integer1[10], integer2[10], integertotal[10];
int i;
for (i = 0; i < 10; i++) {
integer1[i] = 2 * (i + 4);
printf(" %d", integer1[i]);
}
printf("\n");
for (i = 0; i < 10; i++) {
integer2[i] = 3 * (i + 3);
printf(" %d", integer2[i]);
}
printf("\n");
for (i = 0; i < 10; i++) {
integertotal[i] = integer1[i] * 12 + integer2[i] * 10;
printf(" %d", integertotal[i]);
}
printf("\n");
for (i = 0; i < 10; i++)
printf("%d %d+%d=%d\n", i, integer1[i], integer2[i], integertotal[i]); //I don't understand the output you want. 8+9=186? Why?
printf("\n");
return 0;
}
答案 1 :(得分:0)
在第三个循环中,将i和j用作integer1和integer2的索引,因此您尝试访问这两个数组中不存在的11个项目。所以我认为您的代码应该是这样的。
#include <stdio.h>
int main()
{
int integer1[10], integer2[10], integertotal[10];
int i, j, index;
for (i = 0; i < 10; i++)
integer1[i] = 2 * (i + 4);
for (i = 0; i < 10; i++)
printf(" %d", integer1[i]);
printf("\n");
for (j = 0; j < 10; j++)
integer2[j] = 3 * (j + 3);
for (j = 0; j < 10; j++)
printf(" %d", integer2[j]);
printf("\n");
for (index = 0; index < 10; index++)
integertotal[index] = integer1[index] * 12 + integer2[index] * 10;
for (index = 0; index < 10; index++)
printf(" %d", integertotal[index]);
printf("\n\n");
for (index = 0; index < 10; index++)
printf("%d %d+%d=%d\n", index, integer1[index], integer2[index], integertotal[index]);
}
答案 2 :(得分:0)
如何添加两个数组以产生第三个数组?
我们可以编写这样的函数
void sum_arrays(size_t n, int *src_1, int *src_2, int *dest)
{
for (size_t i = 0; i < n; ++i)
{
// Note that 'i' is local, initialized and it is used for all the arrays
dest[i] = src_1[i] + src_2[i];
}
}
这当然不会产生OP期望的输出,但是感谢Bishal Jaiswal,他显然是对“正确”公式进行了反向工程,我们可以使用它
void calc_array(size_t n, int *src_1, int *src_2, int *dest)
{
for (size_t i = 0; i < n; ++i)
{
dest[i] = (src_1[i] * 12 + src_2[i] * 10 + (i + 1)) * 2;
// ^^^ ^^^ ^^^^^
}
}
可测试的HERE。
在问询者发布的代码中,除了使用错误的公式外,数组还使用错误的变量进行了索引
int integer1[10], integer2[10], integertotal[10];
int i, j, index; // <---
for (i = 0; i < 10; i++)
// ...
for (j = 0; j < 10; j++)
// ...
// Now both 'i' and 'j' are equal to 10
// ...
for (index = 0; index < 10; index++)
integertotal[index] = integer1[i] * 12 + integer2[j] * 10;
// Those are out of bounds now ^^^ ^^^
// ...
// Same later
for (index = 0; index < 10; index++)
printf("%d %d+%d=%d\n", index, integer1[i], integer2[j], integertotal[index]);
// ^^^ ^^^