-1

I am getting confused with the standard input of these programming languages :

[Note:]

I added details about so many programming languages as the problem with all of them is same in this matter and my only focus in this question is how can I overcome this problem and have a true terminal like experience from within the program itself.

Firstly,

Java

Code:

import java.util.Scanner;
public class Try{
  public static void main(String args[]){
    Scanner sc = new Scanner(System.in);
    System.out.println("Enter a String : ");
    String s = sc.nextLine();
    System.out.println("The Entered String is : " + s);
    System.out.println("The Length of Entered String is : " + s.length());
    sc.close();
  }
}

Output:

┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $java Try
Enter a String : 
hello
The Entered String is : hello
The Length of Entered String is : 5
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $java Try
Enter a String : 
hello^[[C
The Entered String is : hello
The Length of Entered String is : 8

When I press the arrow keys ^[[C show up instead of the cursor moving (similar thing happens with other arrow keys, escape key, home, end)!

But even in this case how it is becoming 8? and when i print them why are they not showing up as '[', 'C', '^' are printable.

Python

Same as Java here!

Code:

s = input("Enter a String : \n")
print("The Entered String is : " + s)
print("The Length of Entered String is : " + str(len(s)))

Output:

┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $python try.py
Enter a String : 
hello
The Entered String is : hello
The Length of Entered String is : 5
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $python try.py
Enter a String : 
hello^[[D
The Entered String is : hello
The Length of Entered String is : 8

C

Same thing here too..

Code :

#include <stdio.h>

int main()
{
   char s[20];
   int len = 0;
   printf("Enter a String : \n");
   scanf("%[^\n]%*c", s);
   while (s[len] != '\0')
    len++;
   printf("The Entered String is : %s\n", s);
   printf("The Length of Entered String is : %d\n", len);
   return 0;
}

Output:

─[jaysmito@parrot]─[~/Desktop]
└──╼ $gcc -o tryc -Os try.c
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./tryc
Enter a String : 
hello
The Entered String is : hello
The Length of Entered String is : 5
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./tryc
Enter a String : 
hello^[[C
The Entered String is : hello
The Length of Entered String is : 8

But with a slightly different code :

Code:

#include <stdio.h>
#define MAX_LIMIT 20
int main()
{
   char s[MAX_LIMIT];
   int len = 0;
   printf("Enter a String : \n");
   fgets(s, MAX_LIMIT, stdin);
   while (s[len] != '\0')
    len++;
   printf("The Entered String is : %s\n", s);
   printf("The Length of Entered String is : %d\n", len);
   return 0;
}

Output:

┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $gcc -o tryc -Os try.c
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./tryc
Enter a String : 
hello
The Entered String is : hello

The Length of Entered String is : 6
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./tryc
Enter a String : 
hello^[[C
The Entered String is : hello

The Length of Entered String is : 9

Here we cal see clearly that it takes the \n too as a part of the string so 9

C++

Same here too ..

Code:

#include <iostream>
#include <string>
using namespace std;

int main(){
    string s;
    cout << "Enter a string : " << endl;
    cin >> s;
    cout << "The Entered String is : " << s << endl;
    cout << "The Length of Entered String is : " << s.length() << endl;
    return 0;
}

Output:

┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $g++ -o trycpp -Os try.cpp
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./trycpp
Enter a string : 
hello
The Entered String is : hello
The Length of Entered String is : 5
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./trycpp
Enter a string : 
hello^[[C
The Entered String is : hello
The Length of Entered String is : 8

Bash

Same here too.. Code:

#!/bin/bash  
  
echo "Enter a String : "  
read str
echo "The Entered String is : $str"  
len=`expr length "$str"`
echo "The Length of Entered String is : $len"  

Output:

┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./try.sh
Enter a String : 
hello
The Entered String is : hello
The Length of Entered String is : 5
┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $./try.sh
Enter a String : 
hello^[[C
The Entered String is : hello
The Length of Entered String is : 8

Exception

But to all this there is a exception

It is with python.

Instead of running code from a file if we use the python interpreter directly:

Here is the Terminal output :

┌─[jaysmito@parrot]─[~/Desktop]
└──╼ $python
Python 3.9.2 (default, Feb 28 2021, 17:03:44) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> s = input("Enter a String : \n")
Enter a String : 
hello
>>> print("The Entered String is : " + s)
The Entered String is : hello
>>> print("The Length of Entered String is : " + str(len(s)))
The Length of Entered String is : 5
>>> s = input("Enter a String : \n")
Enter a String : 
hello
>>> print("The Entered String is : " + s)
The Entered String is : hello
>>> print("The Length of Entered String is : " + str(len(s)))
The Length of Entered String is : 5

Here in spite of pressing the arrow keys or escape or home the output is same.

I looked in whats the string is having thats making it 8 characters long:

['h', 'e', 'l', 'l', 'o', '\x1b', '[', 'C']

But here too [ and C is printable !

Can any one explain whats all these about?

And how can i get rid of them?

If you need any more details or clarity please ask

Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29
  • I think these characters are there but are just not printable. if you print the word letter-by-letter and print their numerical value I think you'll see the "missing" characters – Gal Mar 31 '21 at 10:06
  • @Gal No check i updated the question stating the value of the string – Jaysmito Mukherjee Mar 31 '21 at 10:07
  • Related: https://stackoverflow.com/questions/21384040/why-does-the-terminal-show-a-b-c-d-when-pressing-the-arrow-k. Also Python uses its own shell, so it handles its own input and probably hides unprintables – QBrute Mar 31 '21 at 10:08
  • Those are control characters, what do you expect to happen and why? Pressing "up" simply does not make sense to do and basically all treatments of it are wrong in some cases. – luk2302 Mar 31 '21 at 10:08
  • @Gal and i think '[' and 'C' is printable – Jaysmito Mukherjee Mar 31 '21 at 10:08
  • @QBrute but while running a python program not from interpreter give same result as others – Jaysmito Mukherjee Mar 31 '21 at 10:09
  • @luk2302 I get it pressing 'up' doesn't make sense but 'right arrow' and 'left arrow' makes a lot of sense – Jaysmito Mukherjee Mar 31 '21 at 10:10
  • It's not that `[` and `C` are not printable, it's that "Right arrow" is not printable. "Right arrow" is sent to the shell as `^[[C` – QBrute Mar 31 '21 at 10:11
  • No, they do not make sense either. Not in this context. The shell does not support left and right cursor movement in this situation. – luk2302 Mar 31 '21 at 10:11
  • @QBrute buw when i print the contents of string as a list i get [ and C thus its not as a single character – Jaysmito Mukherjee Mar 31 '21 at 10:12
  • @luk2302 yeah it makes sense as one may need move to move the cursor to modify the input instead or clearing it using backspace and retyping and this is problematic in case of large inputs – Jaysmito Mukherjee Mar 31 '21 at 10:13
  • You basically do not have a cursor here, and you therefore cannot move it, you can only append characters on the right, there is no going back, have you tried hitting backspace / delete and see what happends?! – luk2302 Mar 31 '21 at 10:15
  • @QBrute as far as the other question , this is not only why its but also what may be the solution for all these programming languages i mean how to avoid that using these languages(if possible) – Jaysmito Mukherjee Mar 31 '21 at 10:16
  • @luk2302 delete behaves similarly but backspace works – Jaysmito Mukherjee Mar 31 '21 at 10:17
  • @JaysmitoMukherjee the characters [ and c and printable, but that's not the characters he really entered. This is just how the terminal presents them. He pressed the arrow keys – Gal Mar 31 '21 at 10:36
  • `'\x1b', '[', 'C'` is what you send to the shell when pressing the right arrow key. Those are actual characters that are appended to your input. The python shell however probably handles this on its own, that's why it doesn't get appended to your input there. Also, this has nothing to do with a specific programming language, but with the way the executing shell handles special characters. – QBrute Mar 31 '21 at 10:37
  • @QBrute then how can it be handled here? – Jaysmito Mukherjee Mar 31 '21 at 10:39
  • Not the downvoter, but you should ask 1 question per language, and you should state the expected behavior. What do you want to happen? – rustyx Mar 31 '21 at 10:40
  • It can't, this is just how the shell works. Why do you need to handle it anyway? – QBrute Mar 31 '21 at 10:40
  • @rustyx i put all the languages as its mainly the same issue and for more clarity of the situation and moreover the snippets are very small mostly one line each rest is the unimportant syntax – Jaysmito Mukherjee Mar 31 '21 at 10:41
  • @QBrute main purpose is so that the user can use the arrow keys and may get a similar experience as using a normal terminal while using the program – Jaysmito Mukherjee Mar 31 '21 at 10:42
  • 1
    I see, so you want the user to be able to move the cursor on the program input line? There are solutions for that, but they are specific per language. I know of one for C, but all languages at once is too broad a question for SO. – rustyx Mar 31 '21 at 10:46
  • @rustyx i dont mean to ask the solution for each language but the solution for any and i gave all the language in the question so that any future reader may get a better idea of the problem and people may answer for any language they prefer and with a few answers there will be solution for some of the language which will be helpful to the future readers – Jaysmito Mukherjee Mar 31 '21 at 10:50
  • @rustyx my only aim for being more descriptive is to leave a question which might be useful – Jaysmito Mukherjee Mar 31 '21 at 10:51
  • @rustyx you can answer for even 1 single language! – Jaysmito Mukherjee Mar 31 '21 at 10:52

2 Answers2

3

how it is becoming 8? and when i print them why are they not showing up as '[', 'C', '^' are printable.

The three chars you see when pressing the right arrow key are combined to form an escape sequence. The first character being ESC.

ESC is not printable but is likely consumed by your terminal which is going into a state where it's waiting for something more to come. When it comes, it'll act on it.

0x1b  // ESC
0x5b  // [ - CSI - Control Sequence Introducer
0x43  // C - CUF - Cursor Forward

If you remove the ESC from the output, your terminal will gladly print [C but when preceeded by ESC it forms a command as shown above.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • how can we overcome it? – Jaysmito Mukherjee Mar 31 '21 at 10:22
  • Do you mean how to strip the escape sequences from the input? You can use a library like `ncurses` or `pdcurses` or some platform specific library capable of interpreting these sequences. They are not always of the same length and implementing a robust interpreter from scratch will likely take a lot of time and effort - especially since different terminals emit and understand different escape sequences. – Ted Lyngmo Mar 31 '21 at 10:25
  • and why the exception with python interpreter? – Jaysmito Mukherjee Mar 31 '21 at 10:25
  • It probably has such an interpreter built-in. When running it in interactive mode, you are supposed to be able to use arrow-up to get the previous line etc. – Ted Lyngmo Mar 31 '21 at 10:25
  • not removing the escape sqeuence from the taken input but not having them at all while taking the input (pressing arrow key ould do nothing) – Jaysmito Mukherjee Mar 31 '21 at 10:27
  • 1
    @JaysmitoMukherjee There is no standard way in C++ to do that. Your terminal will send escape sequences. You either use a library to interpret them directly or just discard control characters from what you've read, so that the user gets `[C` instead of the "invisible" sequence. – Ted Lyngmo Mar 31 '21 at 11:50
  • I guess i have an answer https://stackoverflow.com/a/66886788/14911094 – Jaysmito Mukherjee Mar 31 '21 at 11:52
  • @JaysmitoMukherjee That's what I said. You need to use a library or some thing platform specific to do it. None is iin standard C++. – Ted Lyngmo Mar 31 '21 at 12:06
0

The '\x1b', '[', 'C' is the sequence of characters send to the shell from the keyboard for representing right arrow key(cursor forward).

How to avoid these in Java :- https://stackoverflow.com/a/66901865/14911094

How to avoid these in C or C++ :- https://stackoverflow.com/a/66886788/14911094

How to avoid these in Python :- https://stackoverflow.com/a/66895907/14911094

How to avoid these in Bash :- [Please edit this if you can]

Jaysmito Mukherjee
  • 1,467
  • 2
  • 10
  • 29