Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision 686912ccff84922e06a89205a52c1eb64f0d8d8e)
+++ libcfa/src/iostream.cfa	(revision 0f107e46be6e9a22fbde07db80c01fda5a0c572d)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 31 11:27:56 2023
-// Update Count     : 1545
+// Last Modified On : Sat Sep  2 14:42:01 2023
+// Update Count     : 1561
 //
 
@@ -922,14 +922,9 @@
 	ISTYPE_VOID_IMPL( long double _Complex & )
 
-	// istype & ?|?( istype & is, const char fmt[] ) {
-	// 	fmt( is, fmt, "" );
-	// 	return is;
-	// } // ?|?
-
-	// istype & ?|?( istype & is, char s[] ) {
-	// 	fmt( is, "%s", s );
-	// 	return is;
-	// } // ?|?
-	// ISTYPE_VOID_IMPL( char * )
+	istype & ?|?( istype & is, const char fmt[] ) {
+		fmt( is, fmt, "" );
+		return is;
+	} // ?|?
+	ISTYPE_VOID_IMPL( const char * )
 
 	// manipulators
@@ -962,15 +957,15 @@
 
 forall( istype & | basic_istream( istype ) ) {
+	istype & ?|?( istype & is, _Istream_Cskip f ) {
+		// printf( "skip %s %d\n", f.scanset, f.wd );
+		if ( f.scanset ) fmt( is, f.scanset, "" );		// no input arguments
+		else for ( f.wd ) fmt( is, "%*c" );
+		return is;
+	}
+	ISTYPE_VOID_IMPL( _Istream_Cskip )
+
 	istype & ?|?( istype & is, _Istream_Cstr f ) {
-		// skip
-		if ( ! f.s ) {
-			// printf( "skip %s %d\n", f.scanset, f.wd );
-			if ( f.wd == -1 ) fmt( is, f.scanset, "" );	// no input arguments
-			else for ( f.wd ) fmt( is, "%*c" );
-			return is;
-		} // if
-
 		const char * scanset = f.scanset;
-		if ( f.flags.delimit ) scanset = f.delimit;		// getline ?
+		if ( f.flags.delimiter ) scanset = f.delimiter;	// getline ?
 
 		size_t len = 0;
@@ -980,4 +975,5 @@
 		fmtstr[0] = '%';
 		if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
+		// no maximum width necessary because text ignored => width is read width
 		if ( f.wd != -1 ) { start += sprintf( &fmtstr[start], "%d", f.wd ); }
 
@@ -1005,7 +1001,11 @@
 			throw (cstring_length){ &cstring_length_vt };
 
-		if ( f.flags.delimit ) {						// getline ?
+		if ( f.flags.delimiter ) {						// getline ?
 			if ( len == 0 ) f.s[0] = '\0';				// empty read => argument unchanged => set empty
-			if ( ! eof( is ) ) fmt( is, "%*c" );		// ignore delimiter
+			if ( ! eof( is ) ) {						// ignore delimiter, may not be present because of width
+				char delimiter;
+				fmt( is, "%c", &delimiter );
+				if ( delimiter != f.delimiter[0] ) ungetc( is, delimiter );
+			} // if
 		} //if
 		return is;
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision 686912ccff84922e06a89205a52c1eb64f0d8d8e)
+++ libcfa/src/iostream.hfa	(revision 0f107e46be6e9a22fbde07db80c01fda5a0c572d)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 31 10:55:35 2023
-// Update Count     : 544
+// Last Modified On : Sat Sep  2 14:42:13 2023
+// Update Count     : 567
 //
 
@@ -388,7 +388,6 @@
 	ISTYPE_VOID( long double _Complex & );
 
-//	istype & ?|?( istype &, const char [] );
-//	istype & ?|?( istype &, char [] );
-//	ISTYPE_VOID( char [] );
+	istype & ?|?( istype &, const char [] );
+	ISTYPE_VOID( const char [] );
 
 	// manipulators
@@ -406,8 +405,22 @@
 // *********************************** manipulators ***********************************
 
+struct _Istream_Cskip {
+	const char * scanset;
+	unsigned wd;										// scan width
+}; // _Istream_Cskip
+
+static inline {
+	_Istream_Cskip skip( const char scanset[] ) { return (_Istream_Cskip)@{ scanset, 0 }; }
+	_Istream_Cskip skip( unsigned int wd ) { return (_Istream_Cskip)@{ 0p, wd }; }
+} // distribution
+forall( istype & | basic_istream( istype ) ) {
+	istype & ?|?( istype & is, _Istream_Cskip f );
+	ISTYPE_VOID( _Istream_Cskip );
+}
+
 struct _Istream_str_base {
 	union {
 		const char * scanset;
-		char delimit[2];
+		char delimiter[2];
 	};
 	int wd;												// width
@@ -417,5 +430,5 @@
 			unsigned char ignore:1;						// do not change input argument
 			unsigned char inex:1;						// include/exclude characters in scanset
-			unsigned char delimit:1;					// delimit character
+			unsigned char delimiter:1;					// delimit character
 			unsigned char rwd:1;						// read width
 		} flags;
@@ -436,8 +449,6 @@
 		return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } };
 	}
-	_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[0] = delimit; fmt.delimit[1] = '\0'; fmt.flags.delimit = true; fmt.flags.inex = true; return fmt; }
+	_Istream_Cstr & getline( _Istream_Cstr & fmt, const char delimiter = '\n' ) {
+		fmt.delimiter[0] = delimiter; fmt.delimiter[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = 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; }
