CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Dec 2005
    Posts
    382

    strcmp stdout, stderr and stdin .. more

    Code:
    class File_Driver {
      FILE *op ; 
      FILE *ip;
      bool op_open ;  
      bool ip_open ; 
    public : 
      File_Driver ( const char* in_file_name, const char* out_file_name )
      : op      (   0   )
      , ip      (   0   ) 
      , op_open ( false ) 
      , ip_open ( false )
      {
        if ( in_file_name ) {
          if ( strcmp ( in_file_name, "stdin" ) == 0 ) {
            op = stdin ; 
          }
        } else {
          ip = fopen ( in_file_name, "rb" ) ; 
          if ( ip ) ip_open = true; 
        }
        if ( out_file_name ) {
          if ( strcmp ( in_file_name, "stdout" ) == 0 ) {
            op = stdout ; 
          }
        } else if ( strcmp ( in_file_name, "stderr" ) == 0 ) {
          op = stderr;
        } else {
          op = fopen ( out_file_name, "wb" ) ; 
          if ( op ) op_open = true; 
        }
      }
    };
    I'm trying to rewrite the source code above to use C++ streams. What I'm not following however, is the string comparisons (strcmp) to stdout, stderr and stdin and assignment to the member variable op if comparisons == 0. Why is that necessary ( not sure if that's some 'Cism') or ... ?

    Thanks in advance

  2. #2
    Join Date
    Aug 2001
    Location
    Stockholm, Sweden
    Posts
    1,664

    Re: strcmp stdout, stderr and stdin .. more

    op = stdin looks like an bug to me... It should probably be ip = stdin

    The string compares are needed to allow "in_file_name" and "out_file_name" to support standard input, output and stderr names... such as stdin, stdout, stderr.

  3. #3
    Join Date
    Dec 2005
    Posts
    382

    Re: strcmp stdout, stderr and stdin .. more

    Quote Originally Posted by j0nas View Post
    op = stdin looks like an bug to me... It should probably be ip = stdin

    The string compares are needed to allow "in_file_name" and "out_file_name" to support standard input, output and stderr names... such as stdin, stdout, stderr.
    So I realize I could use the input/output stream class fstream instead of "FILE", so now:

    Code:
    class File_Driver {
      std::fstream op ;   // or maybe std::ofstream op ;
      std::fstream ip ;    // or maybe std::ifstream  ip ; 
     // FILE *op ; 
     // FILE *ip;
      bool op_open ;  
      bool ip_open ; 
    public : 
      File_Driver ( const char* in_file_name, const char* out_file_name )
      : op      (   0   )
      , ip      (   0   ) 
      , op_open ( false ) 
      , ip_open ( false )
      {
        if ( in_file_name ) {
          if ( strcmp ( in_file_name, "stdin" ) == 0 ) {
            op = stdin ; 
          }
        } else {
          ip = fopen ( in_file_name, "rb" ) ; 
          if ( ip ) ip_open = true; 
        }
        if ( out_file_name ) {
          if ( strcmp ( in_file_name, "stdout" ) == 0 ) {
            op = stdout ; 
          }
        } else if ( strcmp ( in_file_name, "stderr" ) == 0 ) {
          op = stderr;
        } else {
          op = fopen ( out_file_name, "wb" ) ; 
          if ( op ) op_open = true; 
        }
      }
    };
    However, this doesn't compile. I'm not sure if the comparisons and assignments are warranted when I opt for C++ stream facilities. IOW, what is the equivalent C++ approach using fstream?

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: strcmp stdout, stderr and stdin .. more

    Quote Originally Posted by mop65715 View Post
    However, this doesn't compile. I'm not sure if the comparisons and assignments are warranted when I opt for C++ stream facilities. IOW, what is the equivalent C++ approach using fstream?
    First, we have no idea why it doesn't compile since

    1) You failed to show us the proper headers that must be included for any of this code to even start to compile.

    2) You never showed us the compiler errors.
    Code:
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 2: error: name followed by "::" must be a class or namespace
              name... Wild guess: Did you #include the right header?
        std::fstream op ;   // or maybe std::ofstream op ;
        ^
    
    "ComeauTest.c", line 3: error: name followed by "::" must be a class or namespace
              name... Wild guess: Did you #include the right header?
        std::fstream ip ;    // or maybe std::ifstream  ip ; 
        ^
    
    "ComeauTest.c", line 16: error: identifier "strcmp" is undefined,
            If in C++ mode: Did you #include <string.h> or #include <cstring>?
            If in C mode: Did you #include <string.h>?
            if ( strcmp ( in_file_name, "stdin" ) == 0 ) {
                 ^
    
    "ComeauTest.c", line 17: error: identifier "stdin" is undefined
              op = stdin ; 
                   ^
    
    "ComeauTest.c", line 20: error: identifier "fopen" is undefined
            ip = fopen ( in_file_name, "rb" ) ; 
                 ^
    
    "ComeauTest.c", line 24: error: identifier "strcmp" is undefined,
            If in C++ mode: Did you #include <string.h> or #include <cstring>?
            If in C mode: Did you #include <string.h>?
            if ( strcmp ( in_file_name, "stdout" ) == 0 ) {
                 ^
    
    "ComeauTest.c", line 25: error: identifier "stdout" is undefined
              op = stdout ; 
                   ^
    
    "ComeauTest.c", line 27: error: identifier "strcmp" is undefined,
            If in C++ mode: Did you #include <string.h> or #include <cstring>?
            If in C mode: Did you #include <string.h>?
          } else if ( strcmp ( in_file_name, "stderr" ) == 0 ) {
                      ^
    
    "ComeauTest.c", line 28: error: identifier "stderr" is undefined
            op = stderr;
                 ^
    
    "ComeauTest.c", line 30: error: identifier "fopen" is undefined
            op = fopen ( out_file_name, "wb" ) ; 
                 ^
    
    10 errors detected in the compilation of "ComeauTest.c".
    
    In strict mode, with -tused, Compile failed
    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: strcmp stdout, stderr and stdin .. more

    Apart from agreeing with Paul about the non-compilability of the posted code, I would add the following suggestions.

    1. If you are dealing with streams in general then you may want to base your variables on pointers to istream & ostream.
    Code:
      std::ostream *op;
      std::istream *ip;
    2. If the API allows it, change the input parameters to
    Code:
    File_Driver ( const std::string &in_file_name, const std::string &out_file_name )
    Then your string comparisons become something like
    Code:
    if ( in_file_name == "stdin" )
    though you may want to change 'stdin to 'cin'
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  6. #6
    Join Date
    Dec 2005
    Posts
    382

    Re: strcmp stdout, stderr and stdin .. more

    Quote Originally Posted by JohnW@Wessex View Post
    Apart from agreeing with Paul about the non-compilability of the posted code, I would add the following suggestions.

    1. If you are dealing with streams in general then you may want to base your variables on pointers to istream & ostream.
    Code:
      std::ostream *op;
      std::istream *ip;
    2. If the API allows it, change the input parameters to
    Code:
    File_Driver ( const std::string &in_file_name, const std::string &out_file_name )
    Then your string comparisons become something like
    Code:
    if ( in_file_name == "stdin" )
    though you may want to change 'stdin to 'cin'

    Now I tried what you alluded to but I'm clearly missing something

    Code:
    # include <string>
    # include <fstream>
    
    
    class File_Driver {
      std::fstream *op ;   // or maybe std::ofstream op ;
      std::fstream *ip ;    // or maybe std::ifstream  ip ; 
     // FILE *op ; 
     // FILE *ip;
      bool op_open ;  
      bool ip_open ; 
    public : 
      File_Driver (  std::string& in_file_name,  std::string& out_file_name )
      : op      (   0   )
      , ip      (   0   ) 
      , op_open ( false ) 
      , ip_open ( false )
      {
        if ( in_file_name == "stdin" ) {
          op = stdin ; 
        } else {
         //// ip = fopen ( in_file_name, "rb" ) ; 
          if ( ip ) ip_open = true; 
        }
    
        if ( out_file_name == "stdout" ) {
          op = stdout ; 
        } else if ( in_file_name == "stderr"  ) {
          op = stderr;
        } else {
       //   op = fopen ( out_file_name, "wb" ) ; 
          if ( op ) op_open = true; 
        }
      }
    
    };
    1>main.cpp
    1>c:\sw_dev\msvc_2007-orcas\test\test\test_unit.h(39) : error C2440: '=' : cannot convert from 'FILE *__w64 ' to 'std::fstream *'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\sw_dev\msvc_2007-orcas\test\test\test_unit.h(47) : error C2440: '=' : cannot convert from 'FILE *__w64 ' to 'std::fstream *'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\sw_dev\msvc_2007-orcas\test\test\test_unit.h(50) : error C2440: '=' : cannot convert from 'FILE *__w64 ' to 'std::fstream *'
    1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>Build log was saved at "file://c:\sw_dev\msvc_2007-orcas\test\test\Debug\BuildLog.htm"
    1>test - 3 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: strcmp stdout, stderr and stdin .. more

    Quote Originally Posted by mop65715 View Post
    Now I tried what you alluded to but I'm clearly missing something
    The error is self-explanatory:
    Code:
    Your Comeau C/C++ test results are as follows:
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 20: error: a value of type "_iobuf *" cannot be assigned to an
              entity of type "std::fstream *"
            op = stdin ; 
               ^
    
    "ComeauTest.c", line 27: error: a value of type "_iobuf *" cannot be assigned to an
              entity of type "std::fstream *"
            op = stdout ; 
               ^
    
    "ComeauTest.c", line 29: error: a value of type "_iobuf *" cannot be assigned to an
              entity of type "std::fstream *"
            op = stderr;
               ^
    
    3 errors detected in the compilation of "ComeauTest.c".
    
    In strict mode, with -tused, Compile failed
    You are trying to assign pointers to incompatible types. It's equivalent to assigning a pointer to a Car to a pointer to a Giraffe.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: strcmp stdout, stderr and stdin .. more

    The following compiles, since the pointers are now compatible:
    Code:
    #include <string>
    #include <fstream>
    #include <iostream>
    
    class File_Driver {
      std::ostream *op ;   // or maybe std::ofstream op ;
      std::istream *ip ;    // or maybe std::ifstream  ip ; 
      bool op_open ;  
      bool ip_open ; 
    public : 
      File_Driver (  std::string& in_file_name,  std::string& out_file_name )
      : op      (   0   )
      , ip      (   0   ) 
      , op_open ( false ) 
      , ip_open ( false )
      {
        if ( in_file_name == "stdin" ) {
          ip = &std::cin ; 
        } else {
          if ( ip ) ip_open = true; 
        }
    
        if ( out_file_name == "stdout" ) {
          op = &std::cout; 
        } else if ( in_file_name == "stderr"  ) {
          op = &std::cerr;
        } else {
          if ( op ) op_open = true; 
        }
      }
    
    };
    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: strcmp stdout, stderr and stdin .. more

    And as the function is not expected to modify the input parameters then the function API should be...
    Code:
    File_Driver ( const std::string &in_file_name, const std::string &out_file_name )
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured