Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision d0cfcbe143ffc0d91029ca4847800c1f5b0dd049)
+++ libcfa/src/iostream.cfa	(revision 5ad2c6c7bab9a4b0819637348bed71fda99dca4e)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Aug 14 23:07:20 2023
-// Update Count     : 1466
+// Last Modified On : Thu Aug 24 10:25:20 2023
+// Update Count     : 1516
 //
 
@@ -970,14 +970,17 @@
 		} // if
 
+		int check = f.wd - 1;
+
 		// getline
 		if ( f.flags.delimit ) {
-			enum { size = 16 };
+			enum { size = 32 };
 			char fmtstr[size];
 			snprintf( fmtstr, size, "%%%d[^%c]s", f.wd, f.delimit );
-			f.s[f.wd - 1] = '\0';						// insert sentinel
+			if ( ! f.flags.rwd ) f.s[check] = '\0';		// insert sentinel
 			int len = fmt( is, fmtstr, f.s );			// read upto delimiter
+			if ( ! f.flags.rwd && f.s[check] != '\0' )	// sentinel overwritten ?
+				throw (cstring_length){ &cstring_length_vt };
 			if ( len == 0 ) f.s[0] = '\0';				// empty read => argument unchanged => set empty
-			if ( f.s[f.wd - 1] != '\0' )				// sentinel overwritten ?
-				throw (cstring_length){ &cstring_length_vt };
+//			fprintf( stderr, "getline %s %s %d %d %d '%c'\n", fmtstr, f.s, len, f.wd, check, f.s[check] );
 			if ( ! eof( is ) ) fmt( is, "%*c" );		// ignore delimiter
 			return is;
@@ -1007,9 +1010,8 @@
 		} // if
 
-		int check = f.wd - 1;
-		if ( f.flags.rwd ) check += 1;					// provide place for sentinel
-		f.s[check] = '\0';								// insert sentinel
+		if ( ! f.flags.rwd ) f.s[check] = '\0';			// insert sentinel
 		fmt( is, fmtstr, f.s );
-		if ( f.s[check] != '\0' )						// sentinel overwritten ?
+//		fprintf( stderr, "KK %s %d %c\n", fmtstr, check, f.s[check] );
+		if ( ! f.flags.rwd && f.s[check] != '\0' )		// sentinel overwritten ?
 			throw (cstring_length){ &cstring_length_vt };
 		return is;
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision d0cfcbe143ffc0d91029ca4847800c1f5b0dd049)
+++ libcfa/src/iostream.hfa	(revision 5ad2c6c7bab9a4b0819637348bed71fda99dca4e)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 18 10:44:50 2023
-// Update Count     : 512
+// Last Modified On : Thu Aug 24 11:35:02 2023
+// Update Count     : 530
 //
 
@@ -18,5 +18,4 @@
 #include "iterator.hfa"
 #include "Exception.hfa"
-
 
 // *********************************** ostream ***********************************
@@ -432,22 +431,18 @@
 
 static inline {
-	_Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, {scanset}, -1, {.all : 0} }; }
-	_Istream_Cstr skip( unsigned int wd ) { return (_Istream_Cstr){ 0p, {0p}, wd, {.all : 0} }; }
-	_Istream_Cstr & getline( _Istream_Cstr & fmt ) { fmt.delimit = '\n'; fmt.flags.delimit = true; return fmt; }
-	_Istream_Cstr & getline( const char delimit, _Istream_Cstr & fmt ) { fmt.delimit = delimit; fmt.flags.delimit = true; return fmt; }
-//	_Istream_Cstr incl( const char scanset[], char s[] ) { return (_Istream_Cstr){ s, {scanset}, -1, { .flags.inex : false } }; }
-//	_Istream_Cstr incl( const char scanset[], unsigned int wd, char s[] ) { return (_Istream_Cstr){ s, {scanset}, wd, {.flags.inex : false} }; }
-	_Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
-//	_Istream_Cstr excl( const char scanset[], char s[] ) { return (_Istream_Cstr){ s, {scanset}, -1, { .flags.inex : true } }; }
-//	_Istream_Cstr excl( const char scanset[], unsigned int wd, char s[] ) { return (_Istream_Cstr){ s, {scanset}, wd, {.flags.inex : true} }; }
-	_Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
-	_Istream_Cstr ignore( char s[] ) { return (_Istream_Cstr)@{ s, {0p}, -1, {.flags.ignore : true} }; }
-	_Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
+	// width must include room for null terminator
 	_Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, {0p}, wd, {.all : 0} }; }
+	// read width does not include null terminator
 	_Istream_Cstr wdi( unsigned int wd, unsigned int rwd, char s[] ) {
 		if ( wd <= rwd ) throw (cstring_length){ &cstring_length_vt };
 		return (_Istream_Cstr)@{ s, {0p}, rwd, {.flags.rwd : true} };
 	}
-//	_Istream_Cstr & wdi( unsigned int wd, _Istream_Cstr & fmt ) { fmt.wd = wd; return fmt; }
+	_Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, {scanset}, -1, {.all : 0} }; }
+	_Istream_Cstr skip( unsigned int wd ) { return (_Istream_Cstr){ 0p, {0p}, wd, {.all : 0} }; }
+	_Istream_Cstr & getline( _Istream_Cstr & fmt, const char delimit = '\n' ) { fmt.delimit = delimit; fmt.flags.delimit = true; return fmt; }
+	_Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
+	_Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
+	_Istream_Cstr ignore( char s[] ) { return (_Istream_Cstr)@{ s, {0p}, -1, {.flags.ignore : true} }; }
+	_Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
 } // distribution
 forall( istype & | basic_istream( istype ) ) {
