Why does the backspace key print ^? when calling gets() in crystal? - crystal-lang

When I try to correct input for my crystal program (in a zsh terminal on my Mac), a ^? character is printed to the screen for each press of backspace. It's disorienting and does not delete any characters from the screen, but it technically functions just fine as I discovered playing around with this little testing snippet.
a = gets.as(String).chomp
puts a
a = gets # alright then^?^?^?^?^?
puts a # alright
What is going on here? How can I make my input behave as a user would expect, is there something special I can do with STDIN?

I think, it will depend on the terminal that you are using and it is largely independent of the programming language (e.g. it has been reported in Python).
Some terminals send ^H or ^? when you type a backslash. I can also reproduce it in xterm (on Linux) when calling cat, which is roughly similar to getting a line and printing it (in a loop):
$ echo $TERM
xterm
$ cat
abc^H^H^Hdef
def
... while it works with other terminals (same test: typing abc, deleting three characters, then typing def):
$ echo $TERM
xterm-256color
$ cat
def
def
You can use libraries like readline to workaround around it. I have not tried it myself, but this library implements bindings for Crystal: crystal-readline

Related

How to print in the same position in fortran

Is it possible to replace a character in terminal with another character by changing format of print command or at least clear a line in terminal?
It is not possible in standard Fortran. Perhaps try using the GNU Readline library. Related: Autocomplete from directory in Fortran
If you do not use the Windows terminal you can use the ANSI escape codes. For example, this first prints the stars, than moves back to the same line and writes "test" over the stars:
print *, "***********"
print *,achar(27)//"[2A"
print *,"test"
end
Tested on a Linux terminal, will not work in the basic Windows terminal.

Compiled c++ output file displays random character at end of program?

Not sure if this is an appropriate question, but just recently I've noticed that when I run a C++ program in the terminal when it exits it has a % sign after the last output. For example a hello world program says "hello world%". What is this and how do I get rid of it? I'm on OS X, shell is zsh. Unless I am crazy it has never done this until now.
There are two possibilities that I can think of off hand:
1) You aren't printing a carriage return, so the % prompt appears at the end of the printed text instead of on the next line. (Is the % your standard prompt in the shell?)
2) You are printing past the end of a buffer and getting a random character as a result.
I'd guess #1 based on what you describe, but both could cause the behavior.

Python terminal application with interface like nano

This may be a stupid question but I'm not sure how to phrase it in a google-friendly way...
In a terminal if you type something like:
nano some_file
then nano opens up an edit window inside the terminal. A text based application. Ctrl+X closes it again and you see the terminal as it was.
Here's another example:
man ls
How can I make a text based terminal application in python?
I hope this question makes sense, let me know if you need more clarification...
You probably need to use alternative screen buffer. To enable it just print '\0033[?1049h' and for disabling '\0033[?1049l' (Terminal Control Escape Sequences).
http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#The%20Alternate%20Screen%20Buffer
Example:
print('\033[?1049h', end='')
print('Alternative screen buffer')
s = input()
print('\033[?1049l', end='')
print('Normal mode')
print(s) `
This does the trick:
http://docs.python.org/2/howto/curses.html
Example:
import curses
oScreen = curses.initscr()
curses.noecho()
curses.curs_set(0)
oScreen.keypad(1)
oScreen.addstr("Woooooooooooooo\n\n",curses.A_BOLD)
while True:
oEvent = oScreen.getch()
if oEvent == ord("q"):
break
curses.endwin()

What's the Use of '\r' escape sequence?

I have C code like this:
#include<stdio.h>
int main()
{
printf("Hey this is my first hello world \r");
return 0;
}
I have used the \r escape sequence as an experiment. When I run the code I get the output as:
o world
Why is that, and what is the use of \r exactly?
If I run the same code in an online compiler I get the output as:
Hey this is my first hello world
Why did the online compiler produce different output, ignoring the \r?
\r is a carriage return character; it tells your terminal emulator to move the cursor at the start of the line.
The cursor is the position where the next characters will be rendered.
So, printing a \r allows to override the current line of the terminal emulator.
Tom Zych figured why the output of your program is o world while the \r is at the end of the line and you don't print anything after that:
When your program exits, the shell prints the command prompt. The terminal renders it where you left the cursor. Your program leaves the cursor at the start of the line, so the command prompt partly overrides the line you printed. This explains why you seen your command prompt followed by o world.
The online compiler you mention just prints the raw output to the browser. The browser ignores control characters, so the \r has no effect.
See https://en.wikipedia.org/wiki/Carriage_return
Here is a usage example of \r:
#include <stdio.h>
#include <unistd.h>
int main()
{
char chars[] = {'-', '\\', '|', '/'};
unsigned int i;
for (i = 0; ; ++i) {
printf("%c\r", chars[i % sizeof(chars)]);
fflush(stdout);
usleep(200000);
}
return 0;
}
It repeatedly prints the characters - \ | / at the same position to give the illusion of a rotating | in the terminal.
The program is printing "Hey this is my first hello world ", then it is moving the cursor back to the beginning of the line. How this will look on the screen depends on your environment. It appears the beginning of the string is being overwritten by something, perhaps your command line prompt.
The '\r' stands for "Carriage Return" - it's a holdover from the days of typewriters and really old printers. The best example is in Windows and other DOSsy OSes, where a newline is given as "\r\n". These are the instructions sent to an old printer to start a new line: first move the print head back to the beginning, then go down one.
Different OSes will use other newline sequences. Linux and OSX just use '\n'. Older Mac OSes just use '\r'. Wikipedia has a more complete list, but those are the important ones.
Hope this helps!
PS: As for why you get that weird output... Perhaps the console is moving the "cursor" back to the beginning of the line, and then overwriting the first bit with spaces or summat.
\r move the cursor to the begin of the line.
Line breaks are managed differently on different systems. Some only use \n (line feed, e.g. Unix), some use (\r e.g. MacOS before OS X afaik) and some use \r\n (e.g. Windows afaik).
As amaud576875 said, the \r escape sequence signifies a carriage-return, similar to pressing the Enter key. However, I'm not sure how you get "o world"; you should (and I do) get "my first hello world" and then a new line. Depending on what operating system you're using (I'm using Mac) you might want to use a \n instead of a \r.
This is from antiquated technology: The old fashion typewriter style of printer. There was a roller (platen) that advanced the paper and a print head that hammered a metal key against an ink fabric.
\r Return the print head to the left side.
\n Advance the platen one line.
If the \n was not issued, you would type over what was on a line (used mostly for underlining text).
To answer the part of your question,
what is the use of \r?
Many Internet protocols, such as FTP, HTTP and SMTP, are specified in terms of lines delimited by carriage return and newline. So, for example, when sending an email, you might have code such as:
fprintf(socket, "RCPT TO: %s\r\n", recipients);
Or, when a FTP server replies with a permission-denied error:
fprintf(client, "550 Permission denied\r\n");
It is quite useful, when you are running on the unix platform, and need to create a text file
which will be opened on the dos platform.
Unix uses '\n' as its line terminator, and dos uses '\r\n' as its line terminator, so you can use it to create a dos text file.

How to run a C++ program in another C++ program?

I have a simple C++ program that takes in inputs and outputs some string. Like this:
$ ./game
$ what kind of game? type r for regular, s for special.
$ r
$ choose a number from 1 - 10
$ 1
$ no try again
$ 2
$ no try again
$ 5
$ yes you WIN!
Now I want to write a c++ program can runs this c++ program and plays the game automatically without user input and then outputs it to a file or standard output.
Running it would look like this:
./program game r > outputfile
game is the game program, r for playing regular style.
How should I do this? The main reason I need this program is that I want to do automatic testing for a much bigger program.
You could use std::system from <cstdlib>:
std::system("game r > outputfile");
The return value is ./program's, the sole argument must be of type char const *.
There is no standard way to run a program and feed it standard input, though. Judging by your command line, you're on some Unix variant where popen from <stdio.h> should work:
FILE *sub = popen("game r > outputfile", "w");
then write to sub with the stdio functions and read outputfile afterwards.
(But for simple testing, I'd recommend implementing the core logic of your program as a set of functions/classes that can be run by a custom main function in a loop; or pick your favorite scripting language to handle this kind of thing.)
I'd be more efficient to add a caller function to your main source and have it control looping, logging, and feeding input. It would also not require system calls or other magic to pull off. Being a game programmer, we have our games play themselves as much as possible to help with debugging, and almost always this is done via internal code, not through external scripting or system calls. It makes it easier to feed viable input as well.
This scenario cries out for a "script", IMHO.
Bash, Perl, Python - you name it.
SIMPLEST CASE:
Just write a bash script to call ./program game r > outputfile.
Or ./program game r < test_input.txt > test_output.txt
For more advanced scenarios, you might want to look at "expect".
You might also want to look at "STAF", which might be a great way to "automate your automated tests":
http://staf.sourceforge.net/current/STAFFAQ.htm