im having a problem with scanf and gets. and I kno that its bound to errors but I couldn't find any other way. This way, the name is printing out but It doesn't print out the first letter of it.
Here's my code:
#include <stdio.h>
float calculations(int age, float highBP, float lowBP);
char option;
int counter, age;
char temp_name[50];
float highBP, lowBP, riskF, optimalH = 120.0, optimalL = 80.0;
typedef struct {
char name[50]; /*which represents the patient’s name*/
int age; /*which represents the patient’s age*/
float highBP; /*highBP, which represents the patient’s high (systolic) blood pressure*/
float lowBP; /*lowBP, which represents the patient’s low (diastolic) blood pressure*/
float riskF; /*riskFactor, which represents the patient’s risk factor for stroke due to hypertension.*/
}patient;/*end structure patient*/
patient *pRecords[30];
void printMenu()
{
printf("\n---------------------------------------------------------\n");
printf("|\t(N)ew record\t(D)isplay db\t(U)pdate record\t|\n");
printf("|\t(L)oad disk\t(W)rite disk\t(E)mpty disk\t|\n");
printf("|\t(S)ort db\t(C)lear db\t(Q)uit \t\t|\n");
printf("---------------------------------------------------------\n");
printf("choose one:");
}/*end print menu*/
void enter()
{
if(counter == 30)
printf("database full.");
else{
printf("name: ");
while(getchar()=='\n');
gets(temp_name);
strcpy(pRecords[counter]->name , temp_name);
printf("age: "); scanf("%d", &age);
pRecords[counter]->age = age;
printf("highBP: "); scanf("%f", &highBP);
pRecords[counter]->highBP = highBP;
printf("lowBP: "); scanf("%f", &lowBP);
pRecords[counter]->lowBP = lowBP;
float temp = calculations(age, highBP,lowBP);
pRecords[counter]->riskF = temp;
/*printf("name: %s, age: %d, highbp:%.1f, lowBP:%.1f\n", pRecords[counter]->name,pRecords[counter]->age,pRecords[counter]->highBP,pRecords[counter]->lowBP);
printf("risk factor: %.1f\n", pRecords[counter]->riskF);*/
counter ++;
}
}/*end of void enter function*/
memallocate(int counter){
pRecords[counter] = (patient *)malloc (sizeof(patient));
}/*end memallocate function*/
void display()
{
printf("===============================\n");
int i;
for(i=0; i<counter; i++)
{
printf("name: %s\n", pRecords[i]->name);
printf("age: %d\n", pRecords[i]->age);
printf("bp: %.2f %.2f\n", pRecords[i]->highBP, pRecords[i]->lowBP);
printf("risk: %.2f\n\n", pRecords[i]->riskF);
}/*end of for loop*/
printf("========== %d records ==========", counter);
}/*end of display method*/
float calculations(int age, float highBP, float lowBP)
{ float risk;
if((highBP <= optimalH) && (lowBP <= optimalL))
{ risk = 0.0;
if(age >=50)
risk = 0.5;
}
else if(highBP <= optimalH && (lowBP>optimalL && lowBP <=(optimalL+10)))
{ risk= 1.0;
if(age >=50)
risk = 1.5;
}
else if ((highBP >optimalH && highBP <= (optimalH+10))&& lowBP <=optimalL)
{ risk= 1.0;
if(age >=50)
risk= 1.5;
}
else if((highBP > optimalH && highBP <=(optimalH+10)) && (lowBP >optimalL && lowBP <= (optimalL+10)))
{ risk= 2.0;
if(age >=50)
risk = 2.5;
}
else if(highBP < optimalH && (lowBP >(optimalL+11) && lowBP<(optimalL+20)))
{ risk = 3.0;
if(age >=50)
risk = 3.5;
}
else if((lowBP < optimalL) && (highBP >(optimalH+11) && highBP<(optimalH+20)))
{ risk = 3.0;
if(age >=50)
risk = 3.5;
}
else if((highBP>=(optimalH+11) && highBP <= (optimalH+20))&& (lowBP>=(optimalL+11) && lowBP<=(optimalL+20)))
{ risk = 4.0;
if(age >=50)
risk = 4.5;
}
else
{ risk = 5.0;
if(age >=50)
risk = 5.5;
}
return risk;
}/*end of calculation function*/
main()
{
printMenu();
char option=getchar();
while(option != 'q' || option != 'Q'){
if(option == 'N' || option == 'n')
{
memallocate(counter);
enter();
printMenu();
}
if (option == 'L' || option == 'l')
{
printMenu();
}
if(option == 'S' || option == 's')
{
printMenu();
}
if(option == 'D' || option == 'd')
{
display();
printMenu();
}
if(option == 'W' || option == 'w')
{
printMenu();
}
if(option == 'C' || option == 'c')
{
printMenu();
}
if(option == 'U' || option == 'u')
{
printMenu();
}
if(option == 'E' || option == 'e')
{
printMenu();
}
if(option == 'Q' || option == 'q')
{
exit(0);
}
option = getchar();
}/*end while*/
system("pause");
}/*end main*/
sample output:
---------------------------------------------------------
| (N)ew record (D)isplay db (U)pdate record |
| (L)oad disk (W)rite disk (E)mpty disk |
| (S)ort db (C)lear db (Q)uit |
---------------------------------------------------------
choose one: n
name: judy
age: 30
high bp: 110
low bp: 88
3
---------------------------------------------------------
| (N)ew record (D)isplay db (U)pdate record |
| (L)oad disk (W)rite disk (E)mpty disk |
| (S)ort db (C)lear db (Q)uit |
---------------------------------------------------------
choose one: n
name: cindy white
age: 52
high bp: 100.7
low bp: 89.4
---------------------------------------------------------
| (N)ew record (D)isplay db (U)pdate record |
| (L)oad disk (W)rite disk (E)mpty disk |
| (S)ort db (C)lear db (Q)uit |
---------------------------------------------------------
choose one: d
===============================
name: udy
age: 30
bp: 110.00 88.00
risk: 1.0
name: indy white
age: 52
bp: 100.70 89.40
risk: 1.5
========== 2 records ==========
Your while loop and use of gets() is generally not good practice.
Try something like:
fflush(stdin);
fgets(pRecords[counter]->name, sizeof(pRecords[counter]->name), stdin);
Try
if (strlen(pRecords[counter]->name) > 0)
{
pRecords[counter]->name[strlen(pRecords[counter]->name) - 1] = '\0';
}
You lose the first character to while(getchar()=='\n');. I don't know why that statement is necessary, but it loops until it gets a character that is not '\n' (which is 'j' and 'c' in your case).
while (getchar() == '\n');
This line eats the newlines plus one character. When getchar() does not return a newline, it has already consumed the first character.
Look at ungetc() to write that character back onto the stream.
This:
while(getchar()=='\n');
loops until it gets a non-newline, which will be the first character of the name.
Try this instead:
do
c = getchar();
while(c == '\n');
ungetc(c, stdin);
Related
My EA was taking only 1 trade at a time on a single currency pair, it ignores the other pairs till the current trade is closed. I decided to modify it. Now it's no more trading at all.
int Hour = TimeHour(TimeCurrent());
int DayOfWeek = DayOfWeek();
int total = OrdersTotal();
int count=0;
for(int i=0; i<total; i++)
{
if(OrderSelect(i,SELECT_BY_POS) && OrderSymbol() == _Symbol && OrderMagicNumber()==MagicNumber)
{
Alert("Inside Order Select if");
// Checking if spread is less than 2.0 pips.
if(current_spread <= AllowableSpread)
{
// Checking for days of the week
if(DayOfWeek >= 1 && DayOfWeek <= 5)
{
// Checking for time of the day
if(Hour >= 3 && Hour <= 20)
{
if(ADXValue > 25)
{
if(RSIValue > 50 || RSIValue < 20)
{
if(PreviousFast<PreviousSlow && CurrentFast > CurrentSlow)
ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, Slippage, Ask-(StopLoss*pips), Ask+(TakeProfit*pips), NULL, MagicNumber, 0, Green);
if(ticket<0)
Print("OrderSend failed with error #",GetLastError());
else
Print("OrderSend placed successfully");
}
if(RSIValue < 50 || RSIValue > 70)
{
if(PreviousFast>PreviousSlow && CurrentFast < CurrentSlow)
ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*pips), Bid-(TakeProfit*pips), NULL, MagicNumber, 0, Red);
if(ticket<0)
Print("OrderSend failed with error #",GetLastError());
else
Print("OrderSend placed successfully");
}
}
}
How can I create function that convert large number into shorten number with character in Dart?
like
1000 => 1K
10000 => 10K
1000000 => 1M
10000000 => 10M
1000000000 => 1B
There is a built-in function in Dart that can be used and it's simple:
var f = NumberFormat.compact(locale: "en_IN");
print(f.format(12345));
to make it a method:
getShortForm(var number) {
var f = NumberFormat.compact(locale: "en_US");
return f.format(number);
}
for this to work import
import 'package:intl/intl.dart';
Refer to this doc for more https://pub.dev/documentation/intl/latest/intl/NumberFormat-class.html
If you are looking for a hard way:
getShortForm(int number) {
var shortForm = "";
if (number != null) {
if (number < 1000) {
shortForm = number.toString();
} else if (number >= 1000 && number < 1000000) {
shortForm = (number / 1000).toStringAsFixed(1) + "K";
} else if (number >= 1000000 && number < 1000000000) {
shortForm = (number / 1000000).toStringAsFixed(1) + "M";
} else if (number >= 1000000000 && number < 1000000000000) {
shortForm = (number / 1000000000).toStringAsFixed(1) + "B";
}
}
return shortForm;
}
String toString(int value) {
const units = <int, String>{
1000000000: 'B',
1000000: 'M',
1000: 'K',
};
return units.entries
.map((e) => '${value ~/ e.key}${e.value}')
.firstWhere((e) => !e.startsWith('0'), orElse: () => '$value');
}
A simpler approach, if you only need the suffix. It may not be compiling, but this is the idea.
String getSuffix (int t)
{
int i = -1;
for ( ; (t /= 1000) > 0 ; i++ );
return ['K','M','B'][i];
}
Edit
This is the mathematical way to do it, and it compiles. The point is you are searching for the amount of "groups of 3 decimal" places:
x 000 - 1
x 000 000 - 2
and so on. Which is log1000 number.
String getSuffix (int num)
{
int i = ( log(num) / log(1000) ).truncate();
return (num / pow(1000,i)).truncate().toString() + [' ','K','M','B'][i];
}
The Intl package does this as "compact" numbers, but it has a fixed format and it will also change with different locales, which might or might not be what you want.
Make a class and used its static method every where.
class NumberFormatter{
static String formatter(String currentBalance) {
try{
// suffix = {' ', 'k', 'M', 'B', 'T', 'P', 'E'};
double value = double.parse(currentBalance);
if(value < 1000){ // less than a thousand
return value.toStringAsFixed(2);
}else if(value >= 1000 && value < (1000*100*10)){ // less than a million
double result = value/1000;
return result.toStringAsFixed(2)+"k";
}else if(value >= 1000000 && value < (1000000*10*100)){ // less than 100 million
double result = value/1000000;
return result.toStringAsFixed(2)+"M";
}else if(value >= (1000000*10*100) && value < (1000000*10*100*100)){ // less than 100 billion
double result = value/(1000000*10*100);
return result.toStringAsFixed(2)+"B";
}else if(value >= (1000000*10*100*100) && value < (1000000*10*100*100*100)){ // less than 100 trillion
double result = value/(1000000*10*100*100);
return result.toStringAsFixed(2)+"T";
}
}catch(e){
print(e);
}
}
}
I have created an expert advisor that calculates some conditions and gives a value either long or short for each condition (+or- 0.1 lots), it then sums all the conditions to give a net long or short position.
It should then either open a new order or close an open one to alter the previous open positions(mlots) to match the target value the trade conditions have calculated(sum) on the change of each new bar; this is done by using the ontick function.
If I use only one or two conditions it works fine, but when I increase the number of conditions (sum can be greater than 0.2 lots or less than -0.2lots) it over trades by one and then closes the position which it should and then over trades by one again which it shouldn't get in to a nasty cycle.
I don't understand why it would work perfectly for two conditions but not for more than two I wonder if anyone has an idea I would be grateful for any input.
This is my first attempt at an EA any thoughts would be greatly appreciated best regards Ken
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2018, K T |
//| https:// |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, K T"
#property link ""
#property version "1.00"
#property strict
#property description "SIMPLE TRADER"
//INPUT PARAMETERS
input double lots=0.1;
input int MagicNumber=1111;//MAGICNO MUST BE UNIQUE
input int condno=1; //1=3/10 10 2=10 10/20 3=ALL
input double test=0.0;
input int spread=1;
input int slippage=10;
input string simble="FTSE100(£)";
input int period=PERIOD_M1;
input double TP=200;
input double SL=100;
input int ma1input=3;
input int ma2input=10;
input int ma3input=20;
input int sleep=0;
//ONINIT TEST FOR CORRECR CONDITIONS
int OnInit()
{
string simble1=simble;
int period1=period;
if (simble1==Symbol()&& period1==Period() && Ask-Bid<=spread)
{
Alert ("CORRECT SYMBOL ", simble," mlots=", mlots(),"sum= ",sum());
Alert ("CORRECT TIME T", period);
return(INIT_SUCCEEDED);
}
else
{
Alert ("INIT FAILED");
Alert ("wrong symbol, time or spread too wide");
return(INIT_FAILED);
}
}
//ON EVERY TICK
void OnTick()
{
double sum1 = sum();
double mlots1 = mlots();
if(sum1 == mlots1)
{
neutral();
return;
}
else if(sum1>mlots1 && mlots1>=0 && mlots1!= sum1)
{
openbuy();
return;
}
else if(sum1>mlots1 && mlots1<0 && mlots1!= sum1)
{
closesell();
return;
}
else if(sum1<mlots1 && mlots1<=0 && mlots1!= sum1)
{
opensell();
return;
}
else if(sum1<mlots1 && mlots1>0 && mlots1!= sum1)
{
closebuy();
return;
}
else
return;
}
//NEUTRAL
void neutral()
{
Alert("T", period, " EQUILIBRIUM ", simble,"/ sum=",sum(),"/ mlots=" ,mlots());
return;
}
//OPEN BUY
void openbuy()
{
double TakeProfitLevel;
double StopLossLevel;
TakeProfitLevel = Bid + TP*Point*10; //0.00001 * 10 = 0.0001
StopLossLevel = Bid - SL*Point*10;
if(mlots()!= sum())
{
OrderSend(simble, OP_BUY, lots, Ask, slippage*10, StopLossLevel, TakeProfitLevel, "BUY", MagicNumber);//notice that slippage also has to be multiplied by 10
Alert(MagicNumber," T", period, " OPENBUYFCTION = ", simble,"/ sum=",sum(),"/ mlots=" ,mlots());
Sleep(sleep);
return;
}
else
{
return;
}
}
//OPEN SELL
void opensell()
{
double TakeProfitLevel;
double StopLossLevel;
//here we are assuming that the TakeProfit and StopLoss are entered in Pips
TakeProfitLevel = Ask - TP*Point*10; //0.00001 * 10 = 0.0001
StopLossLevel = Ask + SL*Point*10;
if (mlots()!= sum())
{
OrderSend(simble, OP_SELL, lots, Bid, slippage*10, StopLossLevel, TakeProfitLevel, "SELL", MagicNumber); //notice that slippage also has to be multiplied by 10
Alert(MagicNumber," T", period, " OPENSELLFCTION = ", simble,"/ sum=",sum(),"/ mlots=" ,mlots());
Sleep(sleep);
return;
}
else
{
return;
}
}
//CLOSE BUY
void closebuy()
{
if(mlots()==sum())
{
neutral();
return;
}
int low=OrderTicket();
int i=OrdersTotal();
for (i = OrdersTotal(); i >=0; i--)
{
if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
if (i<=OrdersTotal() && OrderType()== OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber )
bool closed = OrderClose( low, OrderLots(), Bid, slippage, White);
Alert("Ticket= ", low);
Alert(MagicNumber," T", period, " CLOSEBUYFCTION = ", simble,"/ sum=",sum(),"/ mlots=" ,mlots());
Sleep(sleep);
return;
}
}
//CLOSE SELL
void closesell()
{
if(mlots()==sum())neutral();
int low=OrderTicket();
int i=OrdersTotal();
for (i = OrdersTotal(); i >=0; i--)
{
if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
if (i<=OrdersTotal() && OrderType()== OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber )
bool closed = OrderClose( low, OrderLots(), Ask, slippage, White);
Alert("Ticket= ", low);
Alert(MagicNumber," T", period, " CLOSESELLFCTION = ", simble,"/ sum=",sum(),"/ mlots=" ,mlots());
Sleep(sleep);
return;
}
}
//CONDITION 1
double cond1() //cond 1 3ema 10ma
{
double ma1;
double ma2;
ma1=iMA(NULL,0,ma1input,0,MODE_EMA,PRICE_CLOSE,1);//3EMA
ma2=iMA(NULL,0,ma2input,0,MODE_SMA,PRICE_CLOSE,1);//10MA
if(ma1>=ma2)
{
return(lots);
}
else
{
return(lots*-1);
}
}
//CONDITION 2
double cond2() //cond 2 10ema 10ma
{
double ma1;
double ma2;
ma1=iMA(NULL,0,ma1input,0,MODE_EMA,PRICE_CLOSE,1);//3EMA
ma2=iMA(NULL,0,ma2input,0,MODE_EMA,PRICE_CLOSE,1);//10EMA
if(ma1>=ma2)
{
return(lots);
}
else
{
return(lots*-1);
}
}
//CONDITION 3
double cond3() //cond 3 10ema 20ema
{
double ma1;
double ma2;
ma1=iMA(NULL,0,ma2input,0,MODE_EMA,PRICE_CLOSE,1);//10EMA
ma2=iMA(NULL,0,ma3input,0,MODE_EMA,PRICE_CLOSE,1);//20EMA
if(ma1>=ma2)
{
return(lots);
}
else
{
return(lots*-1);
}
}
//CONDITION 4
double cond4() //cond 4 10ma 20Ema
{
double ma1;
double ma2;
ma1=iMA(NULL,0,ma2input,0,MODE_SMA,PRICE_CLOSE,1);//10MA
ma2=iMA(NULL,0,ma3input,0,MODE_EMA,PRICE_CLOSE,1);//20EMA
if(ma1>=ma2)
{
return(lots);
}
else
{
return(lots*-1);
}
}
//SELECTING CONDITIONS TO BE INCLUDED
double sum()
{
if(condno==1)
{
return(cond1() + cond2());
}
else if(condno==2)
{
return(cond3() + cond4());
}
else if (condno==3)
{
return(cond1() + cond2()+ cond3() + cond4() );//IF MORE THAN TWO CONDITIONS USED IT OVERTRADES B ONE AND THEN CLOSES ERROR TRADE
}
else
return(cond1() + cond2());
}
//COUNT OF ALL OPEN TRADES
double mlots()
{
double mlots1 = BuyTotalMagicOpen() + SellTotalMagicOpen();
double mlots2 = mlots1/10;
return (mlots2);
}
//COUNT BUY ORDERS
double BuyTotalMagicOpen()
{
int OrderCount = 0;
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
if (OrderType() == OP_BUY) OrderCount++;
}
return (OrderCount);
}
//COUNT SELL ORDERS
double SellTotalMagicOpen()
{
int OrderCount = 0;
for (int i = OrdersTotal() - 1; i >= 0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber) continue;
if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
if (OrderType() == OP_SELL) OrderCount++;
}
return (OrderCount*-1);
}
//CLOSE ALL MAGICNUMBER REFRESHRATES BUSYSLEEP MODE
void CloseThis() {
for (int i = OrdersTotal(); i >=0; i--) {
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
while(IsTradeContextBusy()) Sleep(100);
RefreshRates();
if (OrderType() == OP_BUY && Symbol() == OrderSymbol()
&& MagicNumber == OrderMagicNumber()) {
bool closed = OrderClose( OrderTicket(), OrderLots(), Bid, slippage, Red);
Alert("T", period, " BUY CLOSED ON DEINIT");
}
if (OrderType() == OP_SELL && Symbol() == OrderSymbol()
&& MagicNumber == OrderMagicNumber()) {
bool closed = OrderClose( OrderTicket(), OrderLots(), Ask, slippage, Green);
Alert("T", period, " SELL CLOSED ON DEINIT");
}
}
}
//DEINIT
void OnDeinit(const int reason)//MAGIC NO
{
CloseThis();
Alert("T", period, " DEINIT SUCCEEDED");
}
//
I am writing an algorithm to validate IBAN (International Bank Account Number) in Swift 3 and not able to figure one of the validation.
Example IBAN - BE68539007547034
Here are the rules to validate -
Input number should be of length 16.
First 2 characters are country code (not numeric).
Last 14 are numeric.
Last 2 characters are the modulo 97 result of the previous 12 numeric characters.
While #1 - #3 are clear I need clarity on #4. If anyone have done this before and know about it then please let me know.
The validation algorithm is rather simple if you follow the algorithm on wikipedia:
extension String {
private func mod97() -> Int {
let symbols: [Character] = Array(self)
let swapped = symbols.dropFirst(4) + symbols.prefix(4)
let mod: Int = swapped.reduce(0) { (previousMod, char) in
let value = Int(String(char), radix: 36)! // "0" => 0, "A" => 10, "Z" => 35
let factor = value < 10 ? 10 : 100
return (factor * previousMod + value) % 97
}
return mod
}
func passesMod97Check() -> Bool {
guard self.characters.count >= 4 else {
return false
}
let uppercase = self.uppercased()
guard uppercase.range(of: "^[0-9A-Z]*$", options: .regularExpression) != nil else {
return false
}
return (uppercase.mod97() == 1)
}
}
Usage:
let iban = "XX0000000..."
let valid = iban.passesMod97Check()
If you want to validate the format for a specific country, just modify the regular expression, e.g.
"^[A-Z]{2}[0-9]{14}$"
or directly
"^BE\\d{14}$"
From Wikipedia
let IBAN = "GB82WEST12345698765432" // uppercase, no whitespace !!!!
var a = IBAN.utf8.map{ $0 }
while a.count < 4 {
a.append(0)
}
let b = a[4..<a.count] + a[0..<4]
let c = b.reduce(0) { (r, u) -> Int in
let i = Int(u)
return i > 64 ? (100 * r + i - 55) % 97: (10 * r + i - 48) % 97
}
print( "IBAN \(IBAN) is", c == 1 ? "valid": "invalid")
prints
IBAN GB82WEST12345698765432 is valid
With IBAN from your question it prints
IBAN BE68539007547034 is valid
I finded a great solution that work for me in Objective-C
https://gist.github.com/0xc010d/5301790 you can rewrite for Swift or use bridging header. Objective-C implementation of mod97 IBAN checking algorithm
#import <Foundation/Foundation.h>
#interface NSString (Mod97Check)
- (BOOL)passesMod97Check; // Returns result of mod 97 checking algorithm. Might be used to check IBAN.
// Expects string to contain digits and/or upper-/lowercase letters; space and all the rest symbols are not acceptable.
#end
#import "NSString+Mod97Check.h"
#implementation NSString (Mod97Check)
- (BOOL)passesMod97Check {
NSString *string = [self uppercaseString];
NSInteger mod = 0, length = [self length];
for (NSInteger index = 4; index < length + 4; index ++) {
unichar character = [string characterAtIndex:index % length];
if (character >= '0' && character <= '9') {
mod = (10 * mod + (character - '0')) % 97; // '0'=>0, '1'=>1, ..., '9'=>9
}
else if (character >= 'A' && character <= 'Z') {
mod = (100 * mod + (character - 'A' + 10)) % 97; // 'A'=>10, 'B'=>11, ..., 'Z'=>35
}
else {
return NO;
}
}
return (mod == 1);
}
#end
-(BOOL)isValidIBAN {
NSString *iban = self;
static NSString* const LettersAndDecimals = #"ABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789";
iban = [[iban stringByReplacingOccurrencesOfString:#" " withString:#""] uppercaseString];
NSCharacterSet *invalidChars = [[NSCharacterSet characterSetWithCharactersInString:LettersAndDecimals] invertedSet];
if ([iban rangeOfCharacterFromSet:invalidChars].location != NSNotFound)
{
return NO;
}
int checkDigit = [iban substringWithRange:NSMakeRange(2, 2)].intValue;
iban = [NSString stringWithFormat:#"%#%#",[iban substringWithRange:NSMakeRange(4, iban.length - 4)], [iban substringWithRange:NSMakeRange(0, 4)]] ;
for (int i = 0; i < iban.length; i++) {
unichar c = [iban characterAtIndex:i];
if (c >= 'A' && c <= 'Z') {
iban = [NSString stringWithFormat:#"%#%d%#", [iban substringWithRange:NSMakeRange(0, i)], (c - 'A' + 10),[iban substringWithRange:NSMakeRange(i+1, iban.length - i - 1)]];
}
}
iban = [[iban substringWithRange:NSMakeRange(0, iban.length - 2)] stringByAppendingString:#"00"];
while(true)
{
int iMin = (int)MIN(iban.length, 9);
NSString* strPart = [iban substringWithRange:NSMakeRange(0, iMin)];
int decnumber = strPart.intValue;
if(decnumber < 97 || iban.length < 3)
break;
int del = decnumber % 97;
iban = [NSString stringWithFormat:#"%d%#", del, [iban substringFromIndex:iMin]];
}
int check = 98 - iban.intValue;
return checkDigit == check;
}
Here you go :
func isValidIBAN(text:String) -> Bool {
let ibanRegEx = "[a-zA-Z]{2}+[0-9]{2}+[a-zA-Z0-9]{4}+[0-9]{7}([a-zA-Z0-9]?){0,16}"
let ibanTest = NSPredicate(format:"SELF MATCHES %#", ibanRegEx)
return ibanTest.evaluate(with: text)
}
It's clean, and it works.
I want to know if:
val1 = val2 = val3 ... = val6
I try this:
if (val1 == val2 == val3 == val4 == val5 == val6)
{
}
but it don't work, why?
The == operator only works between pairs of values. When you do this:
val1 == val2 == val3
What's really happening is this:
(val1 == val2) == val3
So if val1 and val2 are equal, the expression in the parenthesis evaluates to true:
true == val3
And then it checks whether true == val3, not whether val1 or val2 == val3. You have to do this instead:
val1 == val2 && val1 == val3
This is getting pretty unwieldy for six variables though. Do you really have six local variables that you have to compare? Perhaps you should store them in an array of some sort. Then you can do:
bool all_equal(int *vals, int length) {
if (length == 0) {
return true;
}
int first = vals[0];
for (int i=1; i < length; i++) {
if (vals[i] != first) {
return false;
}
}
return true;
}
So instead of:
int val1 = ..., val2 = ..., val3 = ..., val4 = ..., val5 = ..., val6 = ...;
if (val1 == val2 && val2 == val3 && val3 == val4 && val4 == val5 && val5 == val6) {
...
}
You would to:
int vals[6] = {..., ..., ..., ..., ..., ...};
if (all_equal(vals, 6)) {
...
}
You can't chain the == operator. Do this:
if (val1 == val2 && val2 == val3 && val3 == val4 && val4 == val5 && val5 == val6) {
// they are all equal
}
Error Issue is already ably explained by other users, I just wanted to share an another approach.
I written a C code using variable number of arguments: 9.9. Variable numbers of arguments I hope you find it interesting
#include<stdio.h>
#include<stdarg.h>
typedef enum {FALSE, TRUE} boolean;
boolean isAllEqual(int count, ...){
va_list ap; // vlist variable
int num = 0;
boolean flag = TRUE;
//Step2: To initialize `ap` using right-most argument that is `c`
va_start(ap, count);
//Step3: Now access vlist `ap` elements using va_arg()
num = va_arg(ap, int);
while(--count){
if (num != va_arg(ap, int)){
flag = FALSE;
break;
}
}
//Step4: Now work done, we should reset pointer to NULL
va_end(ap);
return flag? TRUE: FALSE;
}
int main(){
if(isAllEqual(5, 2, 2, 2, 2, 2))
printf(" Yes, All are equal\n");
else
printf(" No, All are NOT equal\n");
if(isAllEqual(4, 2, 4, 2, 5))
printf(" Yes, All are equal\n");
else
printf(" No, All are NOT equal\n");
return 0;
}
Output:
Yes, All are equal
No, All are NOT equal
Check codepade.
My boolean isAllEqual(int count, ...) function can check any number of integers, count = number of values you wants to compare. e.g. In isAllEqual(4, 2, 4, 2, 5) first 4 means you wants to compare next four values.
A short theory in four points will help you to understand my code.
I would suggest writing a macro or a function(if it is array with big size or if it is allocated at runtime) in this case.