Q1: What does this mean: WriteLn (#$0b)?
$0b should hexadecimal like 0x0b, but what about the # sign?
Q2:
x:=readkey;
if ( x = #5) do...
Does #5 mean five? Then what is the# sign for?
Many thanks.
The # in front of a number represents a character with the indicated value (both decimal, and hex numbers preceded by a $, are accepted). So #5 is the same as chr(5), or CtrlE.
Ah, memories ...
#x is indeed the equivalent of chr(x), like Greg Hewgill said.
I'd like to add a little info.
Extended keys, ie the arrow keys, send zero and the char's code:
ch := ReadKey;
if ch = #0 then
begin // extended key
ch := ReadKey; // <-- read again to get the actual code
end else ...
Related
I have a C function:
Node * first_element_by_path(const Node * node, const char * path, char delimiter);
And a Rust glue function:
pub fn first_element_by_path(node: *mut CNode, path: *const c_char, delimiter: c_char) -> *mut CNode;
It expects a c_char as delimiter. I want to send a char to it, but c_char is a i8 and not a char. How can I convert a Rust char to i8 or c_char in this case?
You are asking the question:
How do I fit a 32-bit number into an 8-bit value?
Which has the immediate answer: "throw away most of the bits":
let c = rust_character as libc::c_char;
However, that should cause you to stop and ask the questions:
Are the remaining bits in the right encoding?
What about all those bits I threw away?
Rust chars allow encoding all Unicode scalar values. What is your desired behavior for this code:
let c = '💩' as libc::c_char;
It's probably not to create the value -87, a non-ASCII value! Or this less-silly and perhaps more realistic variant, which is -17:
let c = 'ï' as libc::c_char;
You then have to ask: what does the C code mean by a character? What encoding does the C code think strings are? How does the C code handle non-ASCII text?
The safest thing may be to assert that the value is within the ASCII range:
let c = 'ï';
let v = c as u32;
assert!(v <= 127, "Invalid C character value");
let v = v as libc::c_char;
Instead of asserting, you could also return a Result type that indicates that the value was out of range.
should I change my function (the one that will call the glue function) to receive a c_char instead of a char?
That depends. That may just be pushing the problem further up the stack; now every caller has to decide how to create the c_char and worry about the values between 128 and 255. If the semantics of your code are such that the value has to be an ASCII character, then encode that in your types. Specifically, you can use something like the ascii crate.
In either case, you push the possibility for failure into someone else's code, which makes your life easier at the potential expense of making the caller more frustrated.
So, I'm teaching myself some Golang by making a simple resource management game with ncurses. I'm using this library to connect Golang to ncurses.
I've made a simple text input panel that takes in one character at a time, displays it, and then adds it to a string composing the user's response. Here's what it looks like:
// Accept characters, printing them until end
ch := window.GetChar()
kstr := gc.KeyString(ch)
response := ""
cur := 0
for kstr != "enter" {
// Diagnostic print to get key code of current character
window.Move(0,0)
window.ClearToEOL()
window.MovePrint(0, 0, ch)
// If its a backspace or delete, remove a character
// Otherwise as long as its a regular character add it
if ((ch == 127 || ch == 8) && cur != 0){
cur--
response = response[:len(response)-1]
window.MovePrint(y, (x + cur), " ")
} else if (ch >= 33 && ch <= 122 && cur <= 52) {
window.MovePrint(y, (x + cur), kstr)
response = response + kstr
cur++
}
// Get next character
ch = window.GetChar()
kstr = gc.KeyString(ch)
}
However, the arrow and function keys seem to be coming up as keycodes already associated with the normal a-zA-Z characters. For example, right-arrow comes up as 67 and F1 as 80. Any ideas what I'm doing wrong here, or if there's a better approach to taking in alphanumerics through ncurses? I'd like to avoid ncurses fields and classes as much as possible, because the point here is to learn Golang, not ncurses. Thanks!
If you do not enable the keypad mode, (n)curses will return the individual bytes which make up a special key.
To fix, add this to your program's initialization:
stdscr.Keypad(true) // allow keypad input
which will return special keys such as right-arrow as values above 255. goncurses has symbols defined for those, e.g., KEY_RIGHT.
What's a correct way to call FormatMessageW in Ruby?
require 'win32api'
FormatMessage = Win32API.new 'kernel32', 'FormatMessageW', 'IPIIPII', 'I'
msg = '\0' * 255
FormatMessage.call 0x00001000 | 0x00000100, nil, 6, 1024, msg, 0, 0
FormatMessage returns not null result but msg contains not readable message. What's wrong?
I believe this is the code you are looking for:
require 'win32api'
FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
FormatMessage = Win32API.new 'kernel32', 'FormatMessageW', 'IPIIPIP', 'I'
msgw = ("\x00" * 256).force_encoding("UTF-16LE")
count = FormatMessage.call FORMAT_MESSAGE_FROM_SYSTEM, nil, 6, 1033, msgw, msgw.size, nil
msgw = msgw[0, count]
msg = msgw.encode("UTF-8")
puts msg
When I run this with Ruby, the output is "The handle is invalid.", which is the correct Windows error message for error code 6.
There were some problems with your original code.
The last argument to FormatMessageW is a pointer, so you should use P instead of I, especially if you want it to work on 64-bit Windows.
In Ruby '\0' is actually a two-byte ASCII string, not a single-byte null character. You can confirm this by running p '\0'.bytes.to_a. It looks like you tried to allocate 255 bytes, but you actually allocated 510 bytes. You should allocate an even number of bytes because wide characters in Windows take 2 bytes.
As #theB pointed out, your first argument to FormatMessageW was wrong, since you specified that FormatMessageW should allocate its own buffer.
You specified language code 1024. I can't find a definition for that. Maybe you meant 1033, which is "English - United States". Specifying 1024 doesn't seem to actually cause problems though.
You should use force_encoding to set the encoding of your string to UTF-16LE, because that is the encoding used for wide strings in Windows (or if it's not exactly the same, at least it is compatible most of the time).
The 6th argument to FormatMessageW should be the number of characters in your buffer (which is the number of bytes divided by 2, by the way). Your code just passed 0 for that argument.
Strings in Ruby can contain any arbitrary bytes, including null characters, but it's not necessarily a good idea to let that happen because things like String#size will return surprising results. FormatMessageW returns the number of characters in the formatted message, so we can use that to trim off the null characters at the end. (Conveniently, FormatMessageW returns 0 if there is an error, so our trimming would result in an empty string.)
You should use String#encode to convert your string from UTF-16LE to UTF-8 because UTF-8 strings are much easier to operate on and print in Ruby.
If you don't care about internationalization and unicode, you could have just used FormatMessageA instead. Here is some code that will work for that:
require 'win32api'
FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
FormatMessage = Win32API.new 'kernel32', 'FormatMessageA', 'IPIIPIP', 'I'
msg = ("\x00" * 256).force_encoding("ASCII-8BIT")
count = FormatMessage.call FORMAT_MESSAGE_FROM_SYSTEM, nil, 6, 1033, msg, msg.size, nil
msg = msg[0, count]
puts msg
P.S. DWORD is an unsigned integer type. I am not sure what the right letter for that is in Ruby's Win32API class; it might be that I represents a signed integer, and should be replaced by something else.
I have not used Visual FoxPro for a while. Today, my ex-colleague asks me how to remove non character from name field, i.e. only a-z and A-Z are allowed. I remember I used a function called strstran to do it. I needed to define a variable contains a-z and A-Z. But I do not remember now. Does someone knows how to handle this problem. Thanks in advance.
Use the CHRTRAN() function.
FUNCTION GetAlphaCharacters
LPARAMETERS tcExpressionSearched
LOCAL lcAllowedCharacters
m.lcAllowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
RETURN CHRTRAN(m.tcExpressionSearched, CHRTRAN(m.tcExpressionSearched, m.lcAllowedCharacters, ""), "")
ENDFUNC
Another option is to use ISALPHA(). This only looks at the left most position in the string but it's not case sensitive.
***This should work, but I haven't tested it.
myresults = ""
myvar = "MyText12"
FOR(i = 1 TO LEN(myvar))
IF ISALPHA( SUBSTR(myvar, i, 1) )
myresults = myresults + SUBSTR(myvar, i, 1)
ENDIF
ENDFOR
RETURN myresults
I know I'm a bit late to the party, but here is a function I wrote to clean out all non-printable ASCII characters from a character string.
CLEAR
* Contains ASCII characters 1 (SOH) and 2 (STX)
cTest = "Garbage Data "
? cTest
cTest = RemoveNonPrintableCharacters(cTest)
? cTest
FUNCTION RemoveNonPrintableCharacters
LPARAMETERS tcExpressionSearched
cCleanExpression = tcExpressionSearched
* Cleans out the first 32 ASCII characters, which are not printable
FOR decCount = 0 TO 31
cCleanExpression = CHRTRAN(m.cCleanExpression, CHR(decCount), "")
ENDFOR
* Also cleans out the non-printable DEL character (ASCII 127)
cCleanExpression = CHRTRAN(m.cCleanExpression, CHR(127), "")
* Return the clean string
RETURN cCleanExpression
ENDFUNC
Image http://img534.imageshack.us/img534/8542/aaagla.jpg
It is good to give me a example (any language)
The traditional way to do this is with a stack. Push when you get an open tag, and pull when you get a close tag. Pulling from an empty stack or having a non-zero stack at the end indicates mismatched tags.
Pseudocode
input: lineopen (line having opening tag)
input: text (test as array of lines)
output: lineclose (line having closing tag)
line := lineopen
counter := 1
do
line := line + 1
if text[line] contains opening tag
then counter := counter + 1
if text[line] contains closing tag
then counter := counter - 1
while counter > 0
lineclose := line