|
-
January 17th, 2009, 06:10 PM
#1
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
-
January 17th, 2009, 06:23 PM
#2
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.
-
January 18th, 2009, 01:54 PM
#3
Re: strcmp stdout, stderr and stdin .. more
 Originally Posted by j0nas
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?
-
January 18th, 2009, 02:07 PM
#4
Re: strcmp stdout, stderr and stdin .. more
 Originally Posted by mop65715
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
-
January 19th, 2009, 06:42 AM
#5
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
-
January 20th, 2009, 09:11 PM
#6
Re: strcmp stdout, stderr and stdin .. more
 Originally Posted by JohnW@Wessex
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 ==========
-
January 20th, 2009, 09:23 PM
#7
Re: strcmp stdout, stderr and stdin .. more
 Originally Posted by mop65715
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
-
January 20th, 2009, 09:32 PM
#8
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
-
January 21st, 2009, 03:21 AM
#9
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|