Allgemein

Jedes REPL ist ein virtuelles Linux System mit Standard shell Kommandozeile. Weiters wird eine sehr aktuelle C/C++ Compiler Version verwenden. Daher gibt es ein paar Dinge zu beachten.

gets

The function was depreciated in c++11 and removed in c++14

REPLIT verwendet c++17

Alternative fgets oder scanf (siehe unten)

#include <cstdio>

int main() {
  char str[100];
  fgets(str, 100, stdin); 
}

Nachteil: fgets schreibt \n\0 ans Ende! Auch die weitere Alternative getline hat das gleiche Verhalten.

Für den normalen Unterricht sollte daher die Verwendung von scanf vorteilhafter sein.

gets_s

Vom REPLIT C/C++ Compiler nicht unterstützt.

The function gets_s is not a first-class standard function. It is implemented by Visual Studio (mentioned on MSDN) where it is available if you include stdio.h. Interestingly C11 introduces it as a somewhat standard function by mentioning it in Appendix K, “Bounds-Checking interfaces” along with other _s functions. However many compilers have chosen not to implement this interface so it is probably best not to rely on it. [stackoverflow]

scanf

scanf liest Strings nur bis zum ersten Whitespace

scanf("%s",s);

Wenn Leerzeichen gewünscht sind, dann kann ein Scanset [] verwendete werden.

scanf("%[^\n]%*c", str);

Erklärung: das Scanset [^\n] bedeutet “alles lesen bis zum Newline” mit %*c wird weiters noch das \n (Enter Taste) verworfen.

\n

Die return Taste bleibt bei der Eingabe von Zahlenwerten im Buffer. Führt zum überspringen von String-Eingaben. Mehrfache String Eingaben untereinander sind kein Problem. Ebenso mehrere Wert Eingaben (da scanf selbst am Anfang alles verwirft was keine Ziffer ist).

int a;
char s[100];
scanf("%d", &a);
scanf("%*c"); // Entfernt \n aus dem Tastaturpuffer
scanf("%s", s);

cin/cout

Ein- und Ausgabe in C++. Kein “\n” Problem.

#include <iostream>
using namespace std;
int main() {
  cout << "Hello World!\n";
  int n;
  char s[100];
  cin >> n;
  cin >> s;
  cout << s;
}

C oder C++

Frage soll man ein C oder ein C++ REPL verwenden?

C

Automatisch generierter REPL Source Code

#include <stdio.h>

int main(void) {
  printf("Hello World\n");
  return 0;
}

Compiler-Aufruf

clang-7 -pthread -lm -o main main.c

C++

Automatisch generierter REPL Source Code

#include <iostream>

int main() {
  std::cout << "Hello World!\n";
}

Compiler-Aufruf

clang++-7 -pthread -std=c++17 -o main main.cpp

Anmerkungen zu C vs. C++

C “Hello World” ist für Einsteiger etwas komplexer, weil gleich sehr viele unbekannte Schlüsselwörter vorkommen. Das C++ kann aber ohne Änderung der includes auf printf umgeschrieben werden:

#include <iostream>

int main() {
  printf("Hello World\n");
}

Weitere Vorteile von C++ beim “normalen” – nicht objektorientierten programmieren.

Persönliche Anmerkung: da ich in der Verwendung von purem C keinen besonderen Lerneffekt bei den Schülern sehe verwende ich nur C++.

Borland Legacy

getch

Einlesen einer einzelnen Taste.

getch() ist nicht im Funktionsumfang der Standard C Library sondern ein alte Borland Ergänzung. Alternativ kann getchar() verwendet werden – dabei ist aber immer das drücken der Return Taste notwendig. Der Grund liegt darin, dass die Kommandozeil grundsätzlich zeilenorientiert arbeitet und Eingaben erst am Ende der Zeile an das Programm weitergibt. Das ermöglicht auch line editing d.h. löschen mit Backspace.

Mit etwas Aufwand kann getch() implementiert werden ohne die restlichen Abläufe zu verändern:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>

//////////////////////////

char getch()
{
  static struct termios oldt, newt;

  tcgetattr( STDIN_FILENO, &oldt);
  newt = oldt;

  /* 
ECHO echo mode off
ICANON canonical mode off - 
    In noncanonical mode input is available immediately (without the
    user having to type a line-delimiter character), no input
    processing is performed, and line editing is disabled.
*/
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr( STDIN_FILENO, TCSANOW, &newt);

  char c = getchar();

  // reset to original terminal modes
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

  return c;
}

Siehe REPL : ReplGetch

conio.h

kbhit(), gotoxy() etc. lässt sich nachbauen, siehe conio.hin REPL : ReplConio – starten und mit a,s,d,w steuern. Das funktioniert begrenzt sogar am Handy.

Erklärung: in der Funktion cinit wird das Verhalten der Konsole auf Spiele-Tauglich geändert: