WKURLSchemeHandler crashed on ios13,but ios12 or ios13 later it's works fine - ios13

I reference resources
enter image description here
This is my crash stack
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
frame #0: 0x00000001bbb513c4 WebCore`WebCore::blobRegistry() + 20
frame #1: 0x00000001bbb7c484 WebCore`WebCore::createHTTPBodyCFReadStream(WebCore::FormData&) + 32
frame #2: 0x00000001bbb7cec4 WebCore`WebCore::setHTTPBody(_CFURLRequest*, WebCore::FormData*) + 56
frame #3: 0x00000001bab1e48c WebCore`WebCore::ResourceRequest::doUpdatePlatformHTTPBody() + 120
frame #4: 0x00000001bbb763b4 WebCore`WebCore::ResourceRequestBase::updatePlatformRequest(WebCore::HTTPBodyUpdatePolicy) const + 68
frame #5: 0x00000001bab1d018 WebCore`WebCore::ResourceRequest::nsURLRequest(WebCore::HTTPBodyUpdatePolicy) const + 20
frame #6: 0x00000001ba39cb04 WebKit`WebKit::WebURLSchemeTask::nsRequest() const + 68
frame #7: 0x0000000102cd2b8c pregnancy`-[BBURLSchemeHandler webView:startURLSchemeTask:](self=0x00000002830f0f00, _cmd="webView:startURLSchemeTask:", webView=0x000000012ebaea00, urlSchemeTask=0x00000002830f60a0) at BBURLSchemeHandler.m:89:55
frame #8: 0x00000001ba343b34 WebKit`WebKit::WebURLSchemeHandlerCocoa::platformStartTask(WebKit::WebPageProxy&, WebKit::WebURLSchemeTask&) + 128
frame #9: 0x00000001ba39bb64 WebKit`WebKit::WebURLSchemeHandler::startTask(WebKit::WebPageProxy&, WebKit::WebProcessProxy&, unsigned long long, WebCore::ResourceRequest&&, WTF::CompletionHandler<void (WebCore::ResourceResponse const&, WebCore::ResourceError const&, WTF::Vector<char, 0ul, WTF::CrashOnOverflow, 16ul> const&)>&&) + 220
frame #10: 0x00000001ba36c9b4 WebKit`WebKit::WebPageProxy::startURLSchemeTaskShared(WTF::Ref<WebKit::WebProcessProxy, WTF::DumbPtrTraits<WebKit::WebProcessProxy> >&&, WebKit::URLSchemeTaskParameters&&) + 96
frame #11: 0x00000001ba36c91c WebKit`WebKit::WebPageProxy::startURLSchemeTask(WebKit::URLSchemeTaskParameters&&) + 52
frame #12: 0x00000001ba5bc888 WebKit`WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 22416
frame #13: 0x00000001ba149cd4 WebKit`IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&) + 104
frame #14: 0x00000001ba398000 WebKit`WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 32
frame #15: 0x00000001ba134684 WebKit`IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) + 204
frame #16: 0x00000001ba1375bc WebKit`IPC::Connection::dispatchIncomingMessages() + 612
frame #17: 0x00000001c18b79fc JavaScriptCore`WTF::RunLoop::performWork() + 276
frame #18: 0x00000001c18b7cbc JavaScriptCore`WTF::RunLoop::performWork(void*) + 36
frame #19: 0x00000001b2aeca00 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
frame #20: 0x00000001b2aec958 CoreFoundation`__CFRunLoopDoSource0 + 80
frame #21: 0x00000001b2aec0f0 CoreFoundation`__CFRunLoopDoSources0 + 180
frame #22: 0x00000001b2ae723c CoreFoundation`__CFRunLoopRun + 1080
frame #23: 0x00000001b2ae6adc CoreFoundation`CFRunLoopRunSpecific + 464
frame #24: 0x00000001bca87328 GraphicsServices`GSEventRunModal + 104
frame #25: 0x00000001b6bf463c UIKitCore`UIApplicationMain + 1936
frame #26: 0x000000010372b920 pregnancy`main(argc=1, argv=0x000000016d4db7e8) at main.m:19:16
frame #27: 0x00000001b2970360 libdyld.dylib`start + 4
here is my code in my custom scheme handler
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask{
[self.hashTable addObject:urlSchemeTask];
NSString *filePath = [self filePath:urlSchemeTask.request];
BOOL resourceExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if (resourceExist && filePath.length > 0) {
NSString *mineType = [self fileMIMETypeWithCAPIAtFilePath:filePath];
NSData *data = [NSData dataWithContentsOfFile:filePath];
[self sendRequestWithUrlSchemeTask:urlSchemeTask mimeType:mineType requestData:data];
} else {
[[[NSURLSession sharedSession] dataTaskWithRequest:urlSchemeTask.request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!urlSchemeTask) {
return;
}
if ([self.hashTable containsObject:urlSchemeTask]) {
if (error){
[urlSchemeTask didFailWithError:error];
} else {
#try {
[urlSchemeTask didReceiveResponse:response];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
} #catch (NSException *exception) {
} #finally {
}
}
[self.hashTable removeObject:urlSchemeTask];
}
});
}] resume];
}
}
- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)urlSchemeTask {
if ([self.hashTable containsObject:urlSchemeTask]) {
[self.hashTable removeObject:urlSchemeTask];
}
}
I intercept http & https by WKWebView category with code
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method originalMethod1 = class_getClassMethod(self, #selector(handlesURLScheme:));
Method swizzledMethod1 = class_getClassMethod(self, #selector(bbhandlesURLScheme:));
method_exchangeImplementations(originalMethod1, swizzledMethod1);
});
}
+ (BOOL)bbhandlesURLScheme:(NSString *)urlScheme {
if ([urlScheme isEqualToString:#"http"] || [urlScheme isEqualToString:#"https"]) {
return NO; //这里让返回NO,应该是默认不走系统断言或者其他判断啥的
} else {
return [self bbhandlesURLScheme:urlScheme];
}
}
When the webview contains a network interface request,the webview crashed with Thread 1: EXC_BAD_ACCESS (code=1, address=0x18) on my code NSString *filePath = [self filePath:urlSchemeTask.request]; This only occur on iOS 13. On iOS12、 iOS13.5 or ios14、 iOS15 and so on it works fine. Who knows this, please please help me.

Try this before your request in your custom handler.
SEL selector = sel_registerName("_setLoadResourcesSerially:");
id webViewClass = NSClassFromString(#"WebView");
if ([webViewClass respondsToSelector:selector]) {
[webViewClass performSelector:selector withObject:#NO];
}
Thanks for Rick Huang.First I try to call this method by webview instance.The crash also.Then I consult this method in wkwebview source code, I saw this method is a class method. Then I try to call this with webview class instance. It works good. I am very glad. Thanks for one more time.

Related

CAPL multi frame handling for CAN request message 2E SID

I am trying to find an answer where I could able to read the flow control for request message using CAPL program for SID 2E UDS Diagnostic. I have implemented ISOTP protocol on server side for transmitting multi frame response message which is working fine.
I have added below CAPL program for your reference. Now my problem is I want to write a CAPL program which works like a client request message. I have added few keys to trigger the request msg. As I am not able to receive flow control FC and CF consecutive frame while requesting the message. I don't have a CDD file to config in the diganostics panel.
Please could someone help me to fix this issue. At least an example would be really appreciated.
/*#!Encoding:1252*/
includes
{
}
variables
{
//Golbal variables declaration
msTimer timer_DIAG;
byte checkByte0;
message 0x713 msg = { dlc=8}; //0x713 request msg Need help to fix when SID 2E is requested
byte check_byte0;
message 0x71B sendmsg; //0x71B response msg
}
//Request message from client to server 0x713 CAN ID
on message 0x713
{
// tester_DiagReqEds = this.tester_DiagReqEds;
// write(" Request CAN msg 0x723 Received %x", tester_DiagReqEds);
checkByte0 = this.byte(0) & 0x30;
if(checkByte0 == 0x30) //FC frame
{
msg.dlc = 8;
msg.dword(0) = 0x30;
msg.dword(4) = 0x00;
output(msg);
}
}
//send request write data by identifier 2E F190 parameters
on key 'q'
{
msg.byte(0) = 0x09;
msg.byte(1) = 0x2E;
msg.byte(2) = 0xF1;
msg.byte(3) = 0x90;
msg.byte(4) = 0x10;
msg.byte(5) = 0x20;
msg.byte(6) = 0x30;
msg.byte(7) = 0x40;
msg.byte(8) = 0x01;
msg.byte(9) = 0x02;
msg.byte(10) = 0x03;
output(msg);
}
//send request read data by identifier 22 F190 parameters below 8 bytes which is working fine
on key 'e'
{
msg.byte(0) = 0x03;
msg.byte(1) = 0x2E;
msg.byte(2) = 0xF1;
msg.byte(3) = 0x90;
msg.byte(4) = 0x10;
msg.byte(5) = 0x20;
msg.byte(6) = 0x00;
msg.byte(7) = 0x00;
output(msg);
}
//send request to read data by identifier 22 F190 parameters working fine
on key 'w'
{
msg.byte(0) = 0x03;
msg.byte(1) = 0x22;
msg.byte(2) = 0xF1;
msg.byte(3) = 0x90;
msg.byte(4) = 0x00;
msg.byte(5) = 0x00;
msg.byte(6) = 0x00;
msg.byte(7) = 0x00;
output(msg);
}
//response message for flow control frame
on message 0x71B
{
// checkByte0 = this.byte(0) & 0x30;
//
// if(checkByte0 == 0x10)
// {
// sendmsg.dword(0) = 0x30;
// sendmsg.dword(4) = 0x00;
// output(sendmsg);
// }
}
You want to send the payload
2E F1 90 10 20 30 40 50 60 70
using ISO TP.
In order to do so, you have to follow the ISO-TP specification and segment the data into one first frame and (possibly several) consecutive frames. The consecutive frames should only be sent after you have received a flow control frame.
These frames should look like:
First frame: 10 0A 2E F1 90 10 20 30
Consecutive frame: 21 40 50 60 70 00 00 00
Explanation:
10 0A 2E F1 90 10 20 30:
1 in the first nibble means, this is a first frame
0 0A the next three nibbles contain the length of the payload. You want to send 10 bytes, hence 0x00A bytes
After that the first frame contains the first 6 bytes of your payload.
21 40 50 60 70 00 00 00:
2 in the first nibble means, this is a consecutive frame
1 in the second nibble means, that this is the first consecutive frame, the second would have a 2 here and so on.
After that there are the next 7 bytes of your payload.
In CAPL code this would look like:
on key 'q'
{
msg.byte(0) = 0x10;
msg.byte(1) = 0x0A
msg.byte(2) = 0x2E;
msg.byte(3) = 0xF1;
msg.byte(4) = 0x90;
msg.byte(5) = 0x10;
msg.byte(6) = 0x20;
msg.byte(7) = 0x30;
output(msg);
}
on message 0x713
{
checkByte0 = this.byte(0) & 0x30;
if(checkByte0 == 0x30) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
}
So what you have to do is:
Send the first frame, wait for the flow control frame, send the consecutive frame.
Again, there is no need to do this manually. CANoe comes with an implementation of CanTp. IIRC, there is a demo configuration coming with CANoe called "CanTp" or "IsoTp". There is no need to use a CDD.
By the way, there is no difference between "client" and "server" in ISOTP. When you have a working implementation on server side, you can simply use the same logic on client side.
#M.Spiller, thank you for explaining in detail. I have tried as you explained but I am confused when receiving the bytes from CAN request followed by capl code. Below I am adding code where I receive the request from CANOe. I want to know, do I missed something that I need to add a code to server to read request from CANOe. Currently, CANOe is not sending multiframe since it is looking response message from server (FC) I assume. Please could tell me where could be the issue ?
/* just for underestanding Where
#define ISOTP_SF 0x00 /* single frame */
#define ISOTP_FF 0x10 /* first frame */
#define ISOTP_CF 0x20 /* consecutive frame */
#define ISOTP_FC 0x30 /* flow control */
CanData[8] = {0,0,0,0,0,0,0,0}
for(dtcnt=0; dtcnt<RxCAN->DLC; dtcnt++)
{
CanData[dtcnt]= RxCAN->Data[dtcnt];
}*/
switch((uint16_t)RxCAN->StdId){
case TESTER_FUNC: //CAN 0x713 Rq
{
/*Request message from CAN to Diagnostic*/
/*If Isotp Single frame == 0 then read 8 byte data */
dgiIsoTp.IsoTpFrameTypeRcv = (0xF0 & CanData[0]);
if (dgiIsoTp.IsoTpFrameTypeRcv == ISOTP_SF)
{
//Function to read CAN request message flow control
ReadCanMsgfrom_Tester(CanData, TESTER_FUNC);
}
else if(dgiIsoTp.IsoTpFrameTypeRcv == ISOTP_FF)
{
if (TimeOutTickFFtoFC_Enable == 1)
{
TimeOutTickFFtoFC_Enable = 0;
dgiIsoTp.IsoTpFC = 0x0F & CanData[0];
dgiIsoTp.IsoTpBlocksize = CanData[1];
dgiIsoTp.IsoTpST = CanData[2];
dgiIsoTp.IsoTpCfFlag = TP_N_WAIT;
CF_Tick = dgiIsoTp.IsoTpST >> 0x01;
CF_TickEnable = 1;
}
}
break;
}
}
Please need your support me to get an idea. enter image description here
#M.Spiller, thank you so much for responding. I made changes in my code as you explained I forgot to update the 1st byte 0x10 FF. . From the above CAPL code I have added few more line to test and partially it is working.
Initially I have length 17 bytes for write 2E F190. I am writing 7 bytes into memory. I want to read bytes which I have written in memory.
But when I request 22 F190 (I have set max length 17 bytes) where I get don'T receive all the7 bytes which I have written. Please could you notice where the mistake would be ?
on message 0x713
{
checkByte0 = this.byte(0) & 0x30;
write("checkbyte value %x",checkByte0 );
if(checkByte0 == 0x30) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
else if(checkByte0 == 0x10) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
}
//send request write data by identifier 2E F190 parameters
on key 'q'
{
msg.byte(0) = 0x10;
msg.byte(1) = 0x0A;
msg.byte(2) = 0x2E;
msg.byte(3) = 0xF1;
msg.byte(4) = 0x90;
msg.byte(5) = 0x10;
msg.byte(6) = 0x20;
msg.byte(7) = 0x30;
output(msg);
}
In the pitcure you can notice I am able to send multi frame the code is able to receive now.Please let me know if
enter image description here
You want to send the payload
2E F1 90 10 20 30 40 50 60 70
using ISO TP.
In order to do so, you have to follow the ISO-TP specification and segment the data into one first frame and (possibly several) consecutive frames. The consecutive frames should only be sent after you have received a flow control frame.
These frames should look like:
First frame: 10 0A 2E F1 90 10 20 30
Consecutive frame: 21 40 50 60 70 00 00 00
Explanation:
10 0A 2E F1 90 10 20 30:
1 in the first nibble means, this is a first frame
0 0A the next three nibbles contain the length of the payload. You want to send 10 bytes, hence 0x00A bytes
After that the first frame contains the first 6 bytes of your payload.
21 40 50 60 70 00 00 00:
2 in the first nibble means, this is a consecutive frame
1 in the second nibble means, that this is the first consecutive frame, the second would have a 2 here and so on.
After that there are the next 7 bytes of your payload.
In CAPL code this would look like:
on key 'q'
{
msg.byte(0) = 0x10;
msg.byte(1) = 0x0A
msg.byte(2) = 0x2E;
msg.byte(3) = 0xF1;
msg.byte(4) = 0x90;
msg.byte(5) = 0x10;
msg.byte(6) = 0x20;
msg.byte(7) = 0x30;
output(msg);
}
on message 0x713
{
checkByte0 = this.byte(0) & 0x30;
if(checkByte0 == 0x30) //FC frame
{
msg.byte(0) = 0x21;
msg.byte(1) = 0x40;
msg.byte(2) = 0x50;
msg.byte(3) = 0x60;
msg.byte(4) = 0x70;
output(msg);
}
}
So what you have to do is:
Send the first frame, wait for the flow control frame, send the consecutive frame.
Again, there is no need to do this manually. CANoe comes with an implementation of CanTp. IIRC, there is a demo configuration coming with CANoe called "CanTp" or "IsoTp". There is no need to use a CDD.
By the way, there is no difference between "client" and "server" in ISOTP. When you have a working implementation on server side, you can simply use the same logic on client side.

Decrypting an Affine Cipher with Modulus

I'm trying to decrypt the ciphertext vczkh which I know was encoded using an affine cipher with the equation 7x + 8(mod 26). This makes my decryption function p = (c – b) * a^-1 (mod 26) where b = 8, a = 7, c = number corresponding with cipher character starting from 0, and p is the same for plaintext. Since I can't have a fraction I calculated that 11 is congruent to 7 making my function p = (c - 8) * 11. Running this for all five letters gives me NMFWP but I know the answer is supposed to be NOVEL. I do not know what I'm doing wrong.
In order to decrypt and affine cipher given a and b you need to use Dk = a^-1(y-b) mod m where m depends in the cardinality of the alphabet you are currently using (English 26, Italian 21, ...), a^-1 = m-a and k = (a, b).
For instance, vczkh with a=7 and b=8 gets decrypted into nqlmh given a^-1 = m - a = 26 - 7 = 19
So for v, since v is at position 21 in the english alphabet:
v -> 19(21-8) mod 26 -> 247 mod 26 -> 13 that corresponds to n
Here's a Javascript script I wrote
//Getting Args from console
var args = {
"operation" : process.argv[2],
"a" : parseInt(process.argv[3]),
"b" : parseInt(process.argv[4]),
"word" : process.argv[5]
};
var encryptedWord = [];
var decryptedWord = [];
if(!args.operation || !args.a || !args.b || !args.word){
console.log("Arguments are missing, please, use: node \"encrypt/decrypt\" a b word");
return;
} else {
if(typeof args.a === 'number' || typeof args.b === 'number'){
if(typeof args.word !== 'string'){
console.log("Word must be a string");
return;
} else {
// If a and m are coprimes
if(gcdCalc(args.a, 26) === 1){
if(args.operation === "encrypt"){
encryptWord().then(function(encrWord){
console.log("Word "+args.word+" got encrypted into "+encrWord);
});
} else if(args.operation === "decrypt"){
decryptWord().then(function(decrWord){
console.log("Ciphetext "+args.word+" got decrypted into "+decrWord);
});
} else {
console.log("Invalid operation specified. Use encrypt or decrypt.");
return;
}
} else {
console.log("a "+args.a+ " and m 26 are not coprimes");
return;
}
}
} else {
console.log("You must assign an Integer number to a and b. Remember that a must be coprime with m (26)");
return;
}
}
function gcdCalc(a, b) {
if (b) {
return gcdCalc(b, a % b);
} else {
return Math.abs(a);
}
};
function encryptWord(){
return new Promise( function(resolve){
var chars = args.word.split("");
var currInt = 0;
var currEnc = "";
chars.forEach( function( currChar){
currInt = parseInt(currChar, 36) - 10;
// E(a,b)(n) = an + b mod 26
currEnc = mod((args.a * currInt + args.b), 26);
encryptedWord.push(String.fromCharCode(97 + currEnc));
});
return resolve(encryptedWord.join(""));
});
}
function decryptWord(){
return new Promise( function(resolve){
var chars = args.word.split("");
var currInt = 0;
var currEnc = "";
//a^-1 = m - a
var a_1 = 26 - args.a;
chars.forEach( function( currChar){
currInt = parseInt(currChar, 36) - 10;
// D(y) = a^-1 * (y - b) mod 26
currEnc = mod((a_1 * (currInt - args.b)), 26);
decryptedWord.push(String.fromCharCode(97 + currEnc));
});
return resolve(decryptedWord.join(""));
});
}
function mod(n, m) {
var remain = n % m;
return Math.floor(remain >= 0 ? remain : remain + m);
};
To run it you need node, then, you can use it:
Encrypt : node affine-cipher.js encrypt 5 8 affine that becomes ihhwvc
Decrypt : node affine-cipher.js decrypt 5 8 ihhwvc that becomes affine
Notice that a and m MUST be coprime. For instance gcd(a, m) MUST be 1.
The total number of possible keys is 312 since a may vary in 12 different numbers which are coprime with 26 and b may vary in all 26 different number, so 12*26=312.
Hope I've been helpful.

How do I avoid infinite loop in my survey java project?

I've just jumped to the programming field. Please help me to find a reasonable solution to one of my educational projects. In case of incorrect input (for example 'z' in place of a figure) my program starts an infinite loop. I'm looking for the alternative to the infinite loop and catch use. At least, maybe someone could suggest how to empty the tray (the methods available on this site don't work with my Win7, NetBeans IDE 7.4).
OBJECTIVE
Develop a program that allows the determination of a specific number of metrics obtained in a survey.
Data
A company sponsors you for the realization of a survey system to a target prospects. According to data collected on individuals during the day, we can calculate metrics that can help the company to better target customers.
The questions used for the survey are:
Question 1: Did you like to use our product?
Question 2: If the answer to question 1 is yes, you will continue to use our product?
Question 3: Do you plan to use a product of our competitor?
Question 4: On a scale of 1 to 3 (1: bad, 2 neutral, 3 good), how do you consider the reputation of our company?
The specific task is to determine the percentages for each question. For questions 1 to 3, percentages of YES and NO are required. For question 4 the percentages of each possible choice are needed.
The data is stored in a single memory structure during the course of the program. By late afternoon, an agent terminates the program after outputting data. Therefore, we will not persist on files or databases for the moment.
Data or metrics will be posted later in the day in a clear format.
So, the purpose is to realize the capture and storage of data and to calculate metrics.
Here you are my Java code:
package surveyproject;
import java.util.Scanner;
import java.util.ArrayList;
public class SurveyProject {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList TotalSurvey = new ArrayList();
do {
try
{
System.out.println("Welcome to survey !");
System.out.println("1 - New survey");
System.out.println("2 - Publish survey results");
System.out.println("3 - Leave the program");
int new_or_printing_results_or_exit = sc.nextInt();
if (new_or_printing_results_or_exit == 1)
{
// ============== Questions 1 and 2 ================ //
System.out.println("Do you use our product? 1-yes 0-no");
int Q1_using_product = sc.nextInt();
int Q2_using_product_in_future = -1;
if (Q1_using_product == 1)
{
System.out.println("Thanks to use our product. Will you "
+ "continue to use it? 1-yes 0-no");
Q2_using_product_in_future = sc.nextInt();
}
else
{
System.out.println("That's a pity you do not use your product.");
}
// =====///====== Question 1 and 2 ================ //
// ============== Question 3 ================ //
System.out.println("Do you use the products of our competitors? 1-yes 0-no");
int Q3_using_competitor_product = sc.nextInt();
// =====///====== Question 3 ================ //
// ============== Question 4 ================ //
System.out.println("Evaluate our company.");
System.out.println("1 - Bad");
System.out.println("2 - Neutral");
System.out.println("3 - Good");
int Q4_company_reputation_rate = sc.nextInt();
// =====///====== Question 4 ================ //
System.out.println("Thank you for the participation!");
// =========== Save current Survey =========== //
Survey objSurvey = new Survey(Q1_using_product,
Q2_using_product_in_future,
Q3_using_competitor_product,
Q4_company_reputation_rate);
TotalSurvey.add(objSurvey);
// =====///=== Save current Survey =========== //
}
else if (new_or_printing_results_or_exit == 2)
{
PrintSurveyResult(TotalSurvey);
}
else if (new_or_printing_results_or_exit == 3)
{
System.out.println("Thank you to use our system!");
System.exit(0);
}
}
catch(Exception except)
{
System.out.println("You entered incorrect answer. Please,"
+ "try again the survey." );
System.out.println("Total answers: " + total_answers);
System.out.println("Question 1: ");
System.out.println("Yes answered: " + Q1_answer_yes + "(" + (double)Q1_answer_yes/total_answers * 100.0 + "%)");
System.out.println("No answered: " + Q1_answer_no + "(" + (double)Q1_answer_no/total_answers * 100.0 + "%)");
System.out.println("Question 2: ");
System.out.println("Yes answered: " + Q2_answer_yes + "(" + (double)Q2_answer_yes/total_answers * 100.0 + "%)");
System.out.println("No answered: " + Q2_answer_no + "(" + (double)Q2_answer_no/total_answers * 100.0 + "%)");
System.out.println("Question 3: ");
System.out.println("Yes answered: " + Q3_answer_yes + "(" + (double)Q3_answer_yes/total_answers * 100.0 + "%)");
System.out.println("No answered: " + Q3_answer_no + "(" + (double)Q3_answer_no/total_answers * 100.0 + "%)");
System.out.println("Question 4: ");
System.out.println("Bad answered: " + Q4_answer_bad + "(" + (double)Q4_answer_bad/total_answers * 100.0 + "%)");
System.out.println("Neutral answered: " + Q4_answer_neutral + "(" + (double)Q4_answer_neutral/total_answers * 100.0 + "%)");
System.out.println("Good answered: " + Q4_answer_good + "(" + (double)Q4_answer_good/total_answers * 100.0 + "%)");
}
}
package surveyproject;
public class Survey {
int Q1_using_product;
int Q2_using_product_in_future;
int Q3_using_competitor_product;
int Q4_company_reputation_rate;
public Survey (int Q1, int Q2, int Q3, int Q4)
{
Q1_using_product = Q1;
Q2_using_product_in_future = Q2;
Q3_using_competitor_product = Q3;
Q4_company_reputation_rate = Q4;
}
public int getQ1_using_product()
{
return Q1_using_product;
}
public int getQ2_using_product_in_future()
{
return Q2_using_product_in_future;
}
public int getQ3_using_competitor_product()
{
return Q3_using_competitor_product;
}
public int getQ4_company_reputation_rate()
{
return Q4_company_reputation_rate;
}
}

How would I loop back to the start

I am really confused on loops; I am new to C# (I have only ever worked with assembly on 16 and 32 bit micro controllers).
any way I have this code:
{
{
Console.WriteLine("Enter the first number");
Decimal iNumber1;
if (!Decimal.TryParse(Console.ReadLine(), out iNumber1)) { Console.WriteLine("Enter a number dummy"); Console.Read(); return; }
Decimal x = iNumber1;
Console.WriteLine("Enter the second number");
Decimal y = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter 1 for addition");
Console.WriteLine("Enter 2 for subtration");
Console.WriteLine("Enter 3 for multification");
Console.WriteLine("Enter 4 for divition");
int z = Convert.ToInt32(Console.ReadLine());
switch (z)
{
case 1:
Console.WriteLine(x + y);
break;
case 2:
Console.WriteLine(x - y);
break;
case 3:
Console.WriteLine(x * y);
break;
case 4:
Console.WriteLine(x / y);
break;
default:
break;
}
}
Console.ReadLine();
}
}
}
This is just a simple console app calculator; but I want to be able to loop back to the start if a number isn't entered.
This will allow you to run until Esc is pressed.
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
// your code
}

Auto add parentheses to math operation string randomly?

Do you have any idea to add parentheses to math operation string automatically and randomly?
For example.
A given operation string:
57 x 40 - 14 + 84 ÷ 19
I need to auto add parentheses randomly in above string.
so it becomes:
(57 x 40) - 14 + (84 ÷ 19) or
(57 x 40) - (14 + 84 ÷ 19) or
57 x (40 - 14) + (84 ÷ 19) or
57 x (40 - 14 + 84 ÷ 19) or
57 x (40 - (14 + 84) ÷ 19)
It really appreciated for the help!!
Mick,
I assumed three things:
There is always space char between number and operator
All numbers are integers (you can easily change that to other types)
Everything that is not number is operator
Example in C#:
Math m = new Math();
string p = m.DoStuff("57 x 40 - 14 + 84 ÷ 19");
Console.WriteLine(p);
class Math
{
internal string DoStuff(string p)
{
bool isParOpen = false;
Random rnd = new Random();
StringBuilder result = new StringBuilder();
int i;
string[] stack = p.Split(' ');
foreach (var item in stack)
{
if (int.TryParse(item, out i))
{
if (rnd.Next(2) == 1)
{
result.Append(isParOpen ? string.Format("{0}) ", item) : string.Format("({0} ", item));
isParOpen = !isParOpen;
}
else
{
result.Append(item).Append(" ");
}
}
else
{
result.Append(item).Append(" ");
}
}
if (isParOpen)
{
result.Append(")");
}
return result.ToString();
}
}
If you handle the mathematical expresion as a String, you can add parenthesis randomly (Eg. add random chars to a string), and then using an script engine, you can evaluate the expresion.

Resources