Merge pull request #2705 from Russell-S-Harper/add-conio-cgets
Implement conio cgets
This commit is contained in:
@@ -289,6 +289,7 @@ function.
|
||||
<item><ref id="cclear" name="cclear">
|
||||
<item><ref id="cclearxy" name="cclearxy">
|
||||
<item><ref id="cgetc" name="cgetc">
|
||||
<item><ref id="cgets" name="cgets">
|
||||
<item><ref id="chline" name="chline">
|
||||
<item><ref id="chlinexy" name="chlinexy">
|
||||
<item><ref id="clrscr" name="clrscr">
|
||||
@@ -2715,6 +2716,44 @@ see anything that you type. (See the description of <tt/cbm_k_scnkey()/.)
|
||||
</quote>
|
||||
|
||||
|
||||
<sect1>cgets<label id="cgets"><p>
|
||||
|
||||
<quote>
|
||||
<descrip>
|
||||
<tag/Function/Input a string directly to the console.
|
||||
<tag/Header/<tt/<ref id="conio.h" name="conio.h">/
|
||||
<tag/Declaration/<tt/char* __fastcall__ cgets (const char* buffer, int size);/
|
||||
<tag/Description/The function inputs a string of at most <tt/size - 1/
|
||||
characters from the console into <tt/buffer/. It returns when <tt/size - 1/
|
||||
characters or either <tt/CR/ or <tt/LF/ are entered. It also handles both
|
||||
multi-line input and backspacing.
|
||||
<tag/Notes/<itemize>
|
||||
<item>The function echoes <tt/CRLF/ when either <tt/CR/ or <tt/LF/ are read
|
||||
but does NOT append either in <tt/buffer/.
|
||||
<item>The function is only available as fastcall function, so it may only
|
||||
be used in the presence of a prototype.
|
||||
</itemize>
|
||||
<tag/Availability/cc65
|
||||
<tag/See also/
|
||||
<ref id="cgetc" name="cgetc">
|
||||
<tag/Example/<verb>
|
||||
#include <conio.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
char buffer[200], *p;
|
||||
|
||||
cputs ("Type a lot and backspace a lot: ");
|
||||
if (p = cgets (buffer, sizeof(buffer)))
|
||||
cputs (p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</verb>
|
||||
</descrip>
|
||||
</quote>
|
||||
|
||||
|
||||
<sect1>chline<label id="chline"><p>
|
||||
|
||||
<quote>
|
||||
|
||||
@@ -110,6 +110,21 @@ char cgetc (void);
|
||||
** 1 (see below), a blinking cursor is displayed while waiting.
|
||||
*/
|
||||
|
||||
char* __fastcall__ cgets (char* buffer, int size);
|
||||
/* Get a string of characters directly from the console. The function returns
|
||||
** when size - 1 characters or either CR/LF are read. Note the parameters are
|
||||
** more aligned with stdio fgets() as opposed to the quirky "standard" conio
|
||||
** cgets(). Besides providing saner parameters, the function also echoes CRLF
|
||||
** when either CR/LF are read but does NOT append either in the buffer. This is
|
||||
** to correspond to stdio fgets() which echoes CRLF, but prevents a "gotcha"
|
||||
** where the buffer might not be able to accommodate both CR and LF at the end.
|
||||
**
|
||||
** param: buffer - where to save the input, must be non-NULL
|
||||
** param: size - size of the buffer, must be > 1
|
||||
** return: buffer if successful, NULL on error
|
||||
** author: Russell-S-Harper
|
||||
*/
|
||||
|
||||
int cscanf (const char* format, ...);
|
||||
/* Like scanf(), but uses direct keyboard input */
|
||||
|
||||
|
||||
76
libsrc/conio/cgets.c
Normal file
76
libsrc/conio/cgets.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/* Created: 2025-06-15 Russell-S-Harper
|
||||
** Modified: <iso-date> <author>
|
||||
** Notes: <e.g. revisions made to support target, edge cases, bugs, etc.>
|
||||
**
|
||||
** char* __fastcall__ cgets (char* buffer, int size);
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <conio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef CRLF
|
||||
#define CRLF "\r\n"
|
||||
#endif /* CRLF */
|
||||
|
||||
char* __fastcall__ cgets (char* buffer, int size)
|
||||
/* Get a string of characters directly from the console. The function returns
|
||||
** when size - 1 characters or either CR/LF are read. Note the parameters are
|
||||
** more aligned with stdio fgets() as opposed to the quirky "standard" conio
|
||||
** cgets(). Besides providing saner parameters, the function also echoes CRLF
|
||||
** when either CR/LF are read but does NOT append either in the buffer. This is
|
||||
** to correspond to stdio fgets() which echoes CRLF, but prevents a "gotcha"
|
||||
** where the buffer might not be able to accommodate both CR and LF at the end.
|
||||
**
|
||||
** param: buffer - where to save the input, must be non-NULL
|
||||
** param: size - size of the buffer, must be > 1
|
||||
** return: buffer if successful, NULL on error
|
||||
*/
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char w, x, y;
|
||||
char c;
|
||||
|
||||
if (buffer && size > 1) {
|
||||
/* Just need the width */
|
||||
screensize (&w, &y);
|
||||
/* Actually just the last column! */
|
||||
--w;
|
||||
cursor (1);
|
||||
for (buffer[i] = '\0', --size; i < size; ) {
|
||||
c = cgetc ();
|
||||
/* Handle CR/LF */
|
||||
if (strchr (CRLF, c)) {
|
||||
/* Echo CRLF, but don't append either CR/LF */
|
||||
cputs (CRLF);
|
||||
break;
|
||||
}
|
||||
/* Handle backspace */
|
||||
if (c == '\b') {
|
||||
if (i > 0) {
|
||||
/* Remove the character */
|
||||
buffer[--i] = '\0';
|
||||
/* Logic to account for line wrapping */
|
||||
y = wherey ();
|
||||
x = wherex ();
|
||||
y = x? y: y - 1;
|
||||
x = x? x - 1: w;
|
||||
/* Clear the character */
|
||||
gotoxy (x, y);
|
||||
cputc (' ');
|
||||
gotoxy (x, y);
|
||||
}
|
||||
/* Handle regular characters */
|
||||
} else if (isprint (c)) {
|
||||
cputc (c);
|
||||
buffer[i] = c;
|
||||
buffer[++i] = '\0';
|
||||
}
|
||||
}
|
||||
cursor (0);
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return (i > 0)? buffer: NULL;
|
||||
}
|
||||
Reference in New Issue
Block a user