From bug-octave-request at bevo dot che dot wisc dot edu Wed Jan 29 21:20:37 2003 Subject: 2.1.43 -- fscanf(fh,"$s","C"); returns matrix data type instead of string From: "John W. Eaton" To: Bruce Moore Cc: bug-octave at bevo dot che dot wisc dot edu Date: Wed, 29 Jan 2003 21:20:04 -0600 On 28-Jan-2003, Bruce Moore wrote: | Test script | --------------------------------------------------- | $ cat test.m | fh = popen("cat test.dat","r") | [i1,i2,i3] = fscanf(fh,"%i %i %i\n","C") | tval = i1*i2 | [s1,s2,s3] = fscanf(fh,"%s %s %s\n","C") | i1 = str2num(s1); | i2 = str2num(s2); | tval = i1*i2 | pclose(fh) | | Output | --------------------------------------------------- | octave:1> test | fh = | { | id = 3 | name = cat test.dat | mode = r | arch = native | status = open | } | i1 = [](0x0) | i2 = [](0x0) | i3 = [](0x0) | tval = [](0x0) | s1 = [](0x0) | s2 = [](0x0) | s3 = [](0x0) | usage: str2num (s) | error: evaluating if command near line 29, column 3 | error: called from `str2num' in file | `/usr/local/share/octave/2.1.43/m/strings/str2num.m' | error: evaluating assignment expression near line 5, | column 4 | error: near line 5 of file | `/home/moor762/smu/dissertation/yield_management/programs/test.m' | octave:1> system("cat test.dat") | 1 2 3 | 4 5 6 | 7 8 9.0e3ans = 0 Please try the following patch. It seems to fix the problem for me: octave:1> test fh = { id = 3 name = cat test.dat mode = r arch = native status = open } i1 = 1 i2 = 2 i3 = 3 tval = 2 s1 = 4 s2 = 5 s3 = 6 tval = 20 ans = 0 However, sometimes the first fscanf fails. I think this is because of a race condition -- the process has not produced output before the first fscanf. A kluge fix is to modify the script: fh = popen("cat test.dat","r") sleep (0.1); [i1,i2,i3] = fscanf(fh,"%i %i %i\n","C") tval = i1*i2 [s1,s2,s3] = fscanf(fh,"%s %s %s\n","C") i1 = str2num(s1); i2 = str2num(s2); tval = i1*i2 pclose(fh) With this change, I've not seen it fail. Sorry I'm not able to offer a better solution now. Thanks, jwe 2003-01-29 John W. Eaton * c-file-ptr-stream.cc (c_file_ptr_buf::underflow_common): New function. * c-file-ptr-stream.h (c_file_ptr_buf::underflow, c_file_ptr_buf::uflow): Use it. (c_file_ptr_buf): Derive from std::streambuf, not OCTAVE_STD_FILEBUF. Don't cache file descriptor. Index: c-file-ptr-stream.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/c-file-ptr-stream.cc,v retrieving revision 1.11 diff -u -r1.11 c-file-ptr-stream.cc --- c-file-ptr-stream.cc 20 Nov 2002 16:56:48 -0000 1.11 +++ c-file-ptr-stream.cc 30 Jan 2003 03:07:57 -0000 at @ -66,22 +66,28 @@ } c_file_ptr_buf::int_type -c_file_ptr_buf::underflow (void) +c_file_ptr_buf::underflow_common (bool bump) { if (f) - return fgetc (f); + { + int_type c = fgetc (f); + + if (! bump +#if defined (CXX_ISO_COMPLIANT_LIBRARY) + && c != traits_type::eof ()) +#else + && c != EOF) +#endif + ungetc (c, f); + + return c; + } else #if defined (CXX_ISO_COMPLIANT_LIBRARY) return traits_type::eof (); #else return EOF; #endif -} - -c_file_ptr_buf::int_type -c_file_ptr_buf::uflow (void) -{ - return underflow (); } c_file_ptr_buf::int_type Index: c-file-ptr-stream.h =================================================================== RCS file: /usr/local/cvsroot/octave/src/c-file-ptr-stream.h,v retrieving revision 1.13 diff -u -r1.13 c-file-ptr-stream.h --- c-file-ptr-stream.h 20 Nov 2002 16:56:48 -0000 1.13 +++ c-file-ptr-stream.h 30 Jan 2003 03:07:57 -0000 at @ -28,39 +28,17 @@ #endif #include -#include #include -// The c_file_ptr_buf requires a std::filebuf that accepts an open -// file descriptor. This feature, while not part of the ISO C++ -// standard, is supported by a variety of C++ compiler runtimes, -// albeit in slightly different ways. -// -// The C++ runtime libraries shipped with GCC versions < 3.0, Sun Pro, -// Sun Workshop/Forte 5/6, Compaq C++ all support a non-standard filebuf -// constructor that takes an open file descriptor. The almost ISO compliant -// GNU C++ runtime shipped with GCC 3.0.x supports a different non-standard -// filebuf constructor that takes a FILE* instead; starting from GCC 3.1, -// the GNU C++ runtime removes all non-standard std::filebuf constructors -// and provides an extension template class __gnu_cxx::stdio_filebuf -// that supports the the 3.0.x behavior. - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) && ! (defined (__APPLE__) && defined (__MACH__)) -# include -# define OCTAVE_STD_FILEBUF __gnu_cxx::stdio_filebuf -#else -# define OCTAVE_STD_FILEBUF std::filebuf -#endif - class -c_file_ptr_buf : public OCTAVE_STD_FILEBUF +c_file_ptr_buf : public std::streambuf { public: #if !defined (CXX_ISO_COMPLIANT_LIBRARY) typedef int int_type; #else - typedef std::filebuf::int_type int_type; + typedef std::streambuf::int_type int_type; #endif typedef int (*close_fcn) (FILE *); at @ -68,25 +46,16 @@ FILE* stdiofile (void) const { return f; } c_file_ptr_buf (FILE *f_arg, close_fcn cf_arg = fclose) - : -#if defined __GNUC__ && __GNUC__ >= 3 - OCTAVE_STD_FILEBUF (f_arg, std::ios::in | std::ios::out), -#elif defined __INTEL_COMPILER - OCTAVE_STD_FILEBUF (f_arg), -#else - OCTAVE_STD_FILEBUF (f_arg ? fileno (f_arg) : -1), -#endif - f (f_arg), cf (cf_arg), - fd (f_arg ? fileno (f_arg) : -1) + : std::streambuf (), f (f_arg), cf (cf_arg) { } ~c_file_ptr_buf (void); int_type overflow (int_type); - int_type underflow (void); + int_type underflow (void) { return underflow_common (false); } - int_type uflow (void); + int_type uflow (void) { return underflow_common (true); } int_type pbackfail (int_type); at @ -106,7 +75,7 @@ int close (void); - int file_number () const { return fd; } + int file_number () const { return f ? fileno (f) : -1; } static int fclose (FILE *f) { return ::fclose (f); } at @ -118,10 +87,8 @@ private: - int fd; + int_type underflow_common (bool); }; - -#undef OCTAVE_STD_FILEBUF class i_c_file_ptr_stream : public std::istream ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------