Why doesn't this print nomatter what I input? [duplicate] - if-statement

This question already has answers here:
Why does my string not match when reading user input from stdin?
(3 answers)
Closed 11 months ago.
I am new to rust and just learned about user input from the command line, I tried making this simple program to test out. When I run it I don't get any errors but even if I put in "mac" or anything else it doesn't print anything. I would like to understand why this happens, if anyone can explain that I would appreciate it a lot.
here is my code:
use std::io::{stdin, stdout, Write};
fn main() {
print!("State your OS: ");
stdout().flush().expect("Flush Failed!");
let mut input_string = String::new();
stdin()
.read_line(&mut input_string)
.ok()
.expect("Failed to read line!");
if input_string == "mac" {
println!("Mac");
} else if input_string == "windows" {
println!("Windows");
} else if input_string == "linux" {
println!("Linux");
}
}

Your input string has a newline character at the end. This is specified in the documentation of read_line().
One possible solution to your problem would be to trim the string. Example:
use std::io::{stdin, stdout, Write};
fn main() {
print!("State your OS: ");
stdout().flush().expect("Flush Failed!");
let mut input_string = String::new();
stdin()
.read_line(&mut input_string)
.ok()
.expect("Failed to read line!");
let s = input_string.trim();
if s == "mac" {
println!("Mac");
} else if s == "windows" {
println!("Windows");
} else if s == "linux" {
println!("Linux");
}
}
There are other possible approaches to this, but I think in almost all cases it's a good practice to trim() the user input. Note that your user could potentially enter " mac", in which case you would probably want to treat the input as "mac" anyway.

Related

Too much information

I have this code running fine but then it shows too much information and I only want the last line in the code.
Code here:
import scala.io.Source
object CovidWorld {
def main(args: Array[String]): Unit = {
val filename = Source.fromFile("OOPAssignment3.txt")
try{
for (line <- filename.getLines.toList) {
if (line.contains("Malaysia") && line.split(",").apply(7).nonEmpty) {
val allDeathString: String = line.split(",").apply(7)
print("\n\n Malaysia latest total amount of death: " + allDeathString)
}
}
}
finally{
filename.close
//print("\nThe file is now closed")
}
}
}
This is the result I obtain from it.result of the running code
I just want the last line of the information instead of the entire thing. Anyone can figure out how? Thanks in advance for the help :)
You can replace the inside of your try block with:
filename
.getLines
.filter(line => line.contains("Malaysia") && line.split(",").apply(7).nonEmpty)
.toList
.takeRight(1)
.foreach(line => {
val allDeathString: String = line.split(",").apply(7)
print("\n\n Malaysia latest total amount of death: " + allDeathString)
})
The key part for your purposes is takeRight which selects n elements from the end of the list. When n == 1 you're taking only the last match which is what you want here.

Force NSTextField to Only Accept Decimal (#.#) Numbers and Periods

I'm trying to make it so an NSTextField will only accept numbers and periods like 12.4 and 3.6 in a Mac app.
I feel like I'm getting pretty close after reviewing other SO questions, but I can't quite get it. The below code works except that it won't allow . characters. It returns true and doesn't beep at me when I type a . but it won't let the character appear in the field.
class decimalFormatter: NumberFormatter {
override func isPartialStringValid(_ partialString: String, newEditingString newString: AutoreleasingUnsafeMutablePointer<NSString?>?, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
//Allows the text to be deleted
if partialString.isEmpty {
return true
}
//Check for #.# numbers
let charSet = NSCharacterSet(charactersIn: "1234567890.").inverted
if partialString.rangeOfCharacter(from: charSet) != nil{
NSBeep()
return false
}else{
return true
}
}
}
Any idea what I'm doing wrong?
I found a simpler way to do it. Inside controlTextDidChange I just did this:
let charSet = NSCharacterSet(charactersIn: "1234567890.").inverted
let chars = fieldDuration.stringValue.components(separatedBy: charSet)
fieldDuration.stringValue = chars.joined()
It works great!
#Clifton Labrum solution is really great but it doesn't reduce the field to Decimal (#.#), you can stil put some inputs as 1.2.4 which would lead to an error when trying tu cast it to Float.
Here is a draft of an extension that worked fine for me ( In Swift 4 )
public override func controlTextDidChange(_ obj: Notification) {
if let textfield = obj.object as? NSTextField,
textfield == self.quantityTextField {
var stringValue = textfield.stringValue
// First step : Only '1234567890.' - #Clifton Labrum solution
let charSet = NSCharacterSet(charactersIn: "1234567890.").inverted
let chars = stringValue.components(separatedBy: charSet)
stringValue = chars.joined()
// Second step : only one '.'
let comma = NSCharacterSet(charactersIn: ".")
let chuncks = stringValue.components(separatedBy: comma as CharacterSet)
switch chuncks.count {
case 0:
stringValue = ""
case 1:
stringValue = "\(chuncks[0])"
default:
stringValue = "\(chuncks[0]).\(chuncks[1])"
}
// replace string
textfield.stringValue = stringValue
}
}
This prevent multiple occurences of . , even if I know that's not the best algorithmic way to do this. For instance 1.2.4 becomes 1.2 when pasted, and by keyboard you can't add another .

How do I make an interactive command line interface?

I am trying to write a tool to compare my files but I found it difficult to interactive with. I want to support 2 operations: 1) load my files into memory 2) compare the files already loaded.
The idea is like below
while (true) {
getline(&line, &linesize, stdin);
if (strlen(line) < 2) continue;
token = strtok(line, DELIM);
if (!strcmp(token,"load")) {
puts("you want to load something");
} else if (!strcmp(token, "compare")) {
puts("you want to compare something");
} else if (!strcmp(token, "exit")) {
puts("exiting...");
exit(1);
} else {
puts("Cannot parse, try again");
}
}
In terminal, if I want to compare some MyVeryLongFileNameFile.foo and AnotherVeryLongFileNameFile.bar, I can just type diff My\tab Ano\tab \enter and it will auto completes the filenames for me.
I would like to also have these kind of features in my program, like using tab to autocomplete, using up/down to choose from previous commands, etc. How should I achieve this?
Using the ncurses.h library help you accomplish this.

Pocketsphinx returns empty string for hypothesis

I'm using pocketshpinx for speech recognition in a custom C++ application. I noticed that sometimes the hypothesis string returned by the ps_get_hyp() method is an empty string.
Question: Is this an expected behaviour? If so, is there a way to tell pocketsphinx to not give the empty string as a hypothesis?
Following is a snippet of the relevant portion of my code:
do { ReadAudioBuffer(); } while (!in_speech);
while (in_speech) { ReadAudioBuffer(); }
ps_end_utt(ps);
hyp = ps_get_hyp(ps, NULL);
The ReadAudioBuffer() method:
void SpeechRecognizer::ReadAudioBuffer()
{
if ((k = ad_read(ad, adbuf, 2048)) < 0)
{
UE_LOG(LogTemp, Warning, TEXT("Failed to read audio\n"));
return;
}
ps_process_raw(ps, adbuf, k, FALSE, FALSE);
in_speech = ps_get_in_speech(ps);
FPlatformProcess::Sleep(0.005);
}
Question: Is this an expected behaviour?
There is nothing wrong with it
If so, is there a way to tell pocketsphinx to not give the empty string as a hypothesis?
If you said nothing what should be returned then?
FPlatformProcess::Sleep(0.005);
Sleep is not really needed here

Rogue Wave Edit Box text

I want to check if the Text box has some text entered by the user but can't. The statement below always returns false
if (MyLLVTextEdit->getMessage() == NULL)
{
MessageBox(NULL,"No Text", "no Text",NULL);
}
also tried
if (MyLLVTextEdit->getMessage() == "")
{
MessageBox(NULL,"No Text", "no Text",NULL);
}
if (MyLLVTextEdit->getValue() == NULL)
{
MessageBox(NULL,"No Text", "no Text",NULL);
}
if (MyLLVTextEdit->getValue() == "")
{
MessageBox(NULL,"No Text", "no Text",NULL);
}
Any ideas please?
Don't familiar with your library, but you should use strcmp function to compare strings (char*), to check if string is empty, you may call strlen
strlen(MyLLVTextEdit->getMessage()) == 0
operator== may be used only if you use some string classes like std::string QString or whatever
What does getMessage() return? Very unlikely char*, as Rogue Wave has own unicode-capable string classes.
If it a kind of a Rogue Wave string-class, check if there is a method for testing the content for emptiness.
Probably you should use something like:
if (MyLLVTextEdit->getMessage().isNull() )
or
if (MyLLVTextEdit->getMessage().isEmpty() )