So I've recently been trying out D, as many programmers I know are recommending I learn it over C++.
I'm using the DMD Compiler v2.057, and this is my code:
while(cliLoopC)
{
write("?> ");
string iPt_ = std.string.tolower(readln());
switch (iPt_)
{
default: writeln(E_URECCOM); break;
case "test":
writeln("Hello!");
break;
}
}
The program is that, whenever I type in test, so it should go to the case instead of the default, it just prints the contents of E_URECCOM (which is a constant char[] that contains UNRECOGNISED COMMAND\n).
I don't see what's happening to make it do this. Any ideas?
Yes, there's a \n at the end of readln. Try using std.string.strip(readln());
Well... I haven't tried out D, but maybe readln() is including the CR, LF or CR/LF at the end of the string and it should be included in the compared string?
case "test\n":
?
Edit:
Adam D. Ruppe's answer is the correct answer in saying:
Yes, there's a \n at the end of readln. Try using std.string.strip(readln());
I just wanted to throw that in there since my answer still has the check
My answer:
The default case is the catch all case, so it looks best (and is conventional) at the end
like this
while(cliLoopC)
{
write("?> ");
string iPt_ = std.string.tolower(readln());
switch (iPt_)
{
case "test":
writeln("Hello!");
break;
default: writeln(E_URECCOM); break;
}
}
Related
I'm creating my first program on Winform with C++. I have a function and a string input. However, when I run the program, I get the following error with text.size(): "Error C2228 left of '.size' must have class/struct/union"
Relevant code:
private: System::Void bntGet_Click(System::Object^ sender, System::EventArgs^ e) {
in_itext = txtText->Text;
itext = Convert::ToString(in_itext);
for (Int32 index = 1; index <= itext.size(); index++)
{
if (itext[index] == '#')
{
while (itext[index - 1] != ' ')
{
index--;
}
while (itext[index] != ' ')
{
next_email += itext[index];
index++;
if (itext[index] == '\0')
break;
}
break;
}
}
txtEmail->Text = next_email;
}
Any suggestions? Thanks everyone!
Standard warning: While it's certainly possible to write the main body of your application in C++/CLI, or even write the GUI in C++/CLI using WinForms, it is not recommended. C++/CLI is intended for interop scenarios: where C# or other .Net code needs to interface with unmanaged C++, C++/CLI can provide the translation between the two. For primary development, it is recommended to use C# with either WinForms or WPF if you want managed code, or C++ with MFC if you want unmanaged.
That said:
for (Int32 index = 1; index <= itext.size(); index++)
and
"Error C2039 'length': is not a member of 'System::String'"
Size is not how you get the length of a System::String in .Net. For that, you want the Length property. You were close on your second attempt, but you need a capital "L". (size() is how std::string does it, but std::string is a completely different beast from System::String.)
Other issues:
in_itext = txtText->Text;
itext = Convert::ToString(in_itext);
It's already a string, you don't need to convert it.
while (itext[index - 1] != ' ')
{
index--;
}
You can easily run off the beginning of the string if you do this. (You'll get an exception when index is equal to zero.) Add a check against zero.
while (itext[index] != ' ')
{
next_email += itext[index];
index++;
if (itext[index] == '\0')
break;
}
Strings in .Net are not null-terminated, you need to check against the Length.
If we take a step back, what problem are you actually trying to solve here? My best guess is that you've got some text with an email address somewhere in the middle, and you just want to extract the email address. If that's the case, then I'd probably try using a regular expression to extract the email address. You've got the full power of the .Net Library available to you, use it! See Using a regular expression to validate an email address for the regex to use, and read up on regular expressions with the introduction page and class reference.
How does one sort code blocks associated with each case (as part of a large switch case construct) on the basis of the case label?
What I want is to transform -
switch(val)
{
case C_LABEL:
/* do something */
break;
case A_LABEL:
/* do something else*/
break;
case B_LABEL:
/* do something really different */
break;
default:
printf("'val' not recognized");
}
into -
switch(val)
{
case A_LABEL:
/* do something else */
break;
case B_LABEL:
/* do something really different */
break;
case C_LABEL:
/* do something */
break;
default:
printf("'val' not recognized");
}
Turn each case into a one liner:
:fromline,tolineg/case/.,/break/s/\n/§
Sort them:
:fromline,tolinesort
Reformat them:
:fromline,tolines/§/\r/g
Notes:
Visual mode can be a practical way to define the range for those commands.
You could make a macro if you have to do that often.
My AdvancedSorters plugin simplifies the steps outlined in #romainl's answer:
:/^switch/+2,/default:/-1 SortRangesByHeader /case /
The initial range limits the sorting of the lines to the case parts. The :SortRangesByHeader command from the plugin defines ranges based on the case statement, and sorts those.
With a bit of outside help:
:command! -range SortCases execute "<line1>,<line2>!ruby -e 'puts STDIN.read.split(/(?<=\\n)(?=[\\x20\\x09]*(?:case|default)\\b)/).sort'"
then you can do vi{:SortCases<CR> to do what you need to do.
I wrote a plugin to do this with the following command:
:SortBlockBy case
Check it out
https://github.com/chiedo/vim-sort-blocks-by
Someone asked me today how to convert the following if statement to switch:
int i=5;
if(i>10)
{
Do Something;
}
else
{
Do Something else;
}
And I proposed that assuming i is an integer with only positive values:
int i=5;
switch(i)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10: Do Something else;
break;
case default: Do Something;
break;
}
Is there any other, more elegant way of doing it?
There is no direct way of doing that in C#, you can try the following.
int range = (number - 1) / 10;
switch(range)
{
case 0:
Console.WriteLine("1 to 10");
break;
case 1:
Console.WriteLine("11 to 20");
break;
//.,......
default:
break;
}
Not really sure how much clear it would be, IMO, the above approach would reduce the code readability, its better if you use if-else for the range checking. Also the above would work only if the range is constant.
First, note your two code examples (as were originally written) were not equivalent:
You're not Do[ing] Something Else when i==10 in your switch example.
But the original if code was checking on i>10 (as opposed to i>=10).
So case 10: should be explicitly included in your list of cases that fall through to Do Something Else.
To answer your question, I believe in some languages (eg pascal, objective C, I think?) a range similar to this is allowed:
switch(i)
{
case 1-10: // or is it "case 1 .. 10" ?
Do Something else;
break;
case default:
Do Something;
break;
}
But this is not supported in C#. Refer the very final point in the code discussion regarding "stacking" of case labels here MSDN switch(C#)
I started learning Dart today, and I've come across something that my google skills are having trouble finding.
How do I have a fall-through in a non-empty case?
My use case is this: I'm writing a sprintf implementation (since dart doesn't have this too), which would work except for this fall-through thing. When parsing the variable type you can, for example, have "%x" versus "%X" where the upper case type tells the formatter that the output is supposed to be uppercase.
The semi-pseudocode looks like:
bool is_upper = false;
switch (getType()) {
case 'X':
is_upper = true;
case 'x':
return formatHex(is_upper);
}
The other ways I can think of doing this, would one of the following
1:
switch (getType()) {
case 'X': case 'x':
return formatHex('X' == getType());
}
2:
var type = getType();
if (type in ['x', 'X']) {
return formatHex('X' == getType());
}
Now, the second choice almost looks good, but then you have to remember that there are eleven cases, which would mean having eleven if (type in []), which is more typing that I'd like.
So, does dart have some // //$FALL-THROUGH$ that I don't know about?
Thanks.
The Dart specification gives a way for a switch case to continue to another switch case using "continue":
switch (x) {
case 42: print("hello");
continue world;
case 37: print("goodbye");
break;
world: // This is a label on the switch case.
case 87: print("world");
}
It works in the VM, but sadly the dart2js switch implementation doesn't yet support that feature.
From the dart language tour, your example of (2) should be correct.
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeClose();
break;
}
It would be an error if you tried to do something as follows
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break causes an exception to be thrown!!
case 'CLOSED':
executeClose();
break;
}
EDIT: This seems to only have worked due to a bug in the implementation of Dart. See the Dart 1.x language spec, section "17.15 Continue".
The bug is now fixed, as reported in a comment, so this no longer works. Keeping for historical reasons.
Also, a simplification of Lasse's answer is to use a simple continue; instead of continue <label>; as in:
bool is_upper = false;
switch (getType()) {
case 'X':
is_upper = true;
continue;
case 'x':
return formatHex(is_upper);
}
You can't have a non-empty case body in Dart that falls through, this will raise an error.
What I tend to do with anything other than very simple switch statements is to refactor all the common code out into functions, so that you don't have this multi-level control flow in the switch itself.
In other words, something like:
switch (getType()) {
case 'X':
return formatHex(true);
case 'x':
return formatHex(false);
}
There's no reason why you need to have fallthrough. It comes in handy when the actions in a case section can be carried out in toto at the end of another case section, but this method can do that without fallthrough and without making your switch statement complex.
It can also handle more complex cases where there are common actions that aren't included in toto at the end. For example, you may want to do something at the start or in the middle of the case section. Calling common functions handles that more than well enough:
switch (getType()) {
case 'X':
doSomethingOnlyForUpperCase();
doSomethingCommon();
doSomethingElseOnlyForUpperCase();
return formatHex(true);
case 'x':
doSomethingCommon();
return formatHex(false);
}
I actually also do this for languages (such as C) that support this sort of non-empty fall-through since I believe it aids in readability and maintainability.
Dart in 202207, just empty, instead of continue label
PermissionStatus recordStatus =
await Permission.requestSinglePermission(
PermissionName.Microphone);
switch (recordStatus) {
case PermissionStatus.allow:
case PermissionStatus.always:
case PermissionStatus.whenInUse:
return;
default:
break;
}
How can I use a function pointer instead of a switch statement?
A slightly different approach from the link posted by ars: You can use the value from the switch statement as an array index in an array of function pointers. So instead of writing
switch (i) {
case 0: foo(); break;
case 1: bar(); break;
case 2: baz(); break;
}
you can do this
typedef void (*func)();
func fpointers[] = {foo, bar, baz};
fpointers[i]();
Alternatively you can use the function pointers instead of numbers as described in ars's answer.
Here's a page that does a pretty good job of explaining this in C++:
http://oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/FPT/em_fpt.html
EDIT:
Above link is broken as of June 2020. Cached here:
https://web.archive.org/web/20170606042951/http://oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/FPT/em_fpt.html