Thread: c++ strings

  1. #1
    Bonnie
    Guest

    c++ strings

    Hello everyone.
    my question involves casting and c++ strings/
    I am reading a file that consists of a sentence.
    when it is read when/if I come upon letter"C", I need to change it to "C++".
    I thought it would be a snap until i became stuck. can some one take a look?
    thanks
    Bonnie
    Code:
      char ch;
       ch = infile.get();
       while ( ch != EOF )   
    	   {
    	   if (strcmp(ch,"C")=0)
    		   cout << "C++";
    		   else 
    		   ch = infile.get();
    	   cout << ch;
    	   ch = infile.get();
    	   }
       cout << endl;
       
       return 0;
    	}

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    strcmp() is for comparing two C-strings - your first parameter is just a char. Use "ch == 'C'" instead.

    You also have one too many "ch = infile.get();" lines in your while loop - I'll let you figure that one out.

    gg

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    char ch = infile.get();
    if(ch == EOF) ...

    This is, very slightly, bad form. cin.get() returns an int, where the low bits are a character and, generally, the high bits contain "out of band" information. Consider the case where you have a binary file containing every single possible char value. Clearly this is possible, if we use a char we have no way to tell the difference between the actual end of the file, and the character (char)EOF. To catch this you need:

    int ch;
    while((ch = infile.get())!=EOF) { ...

    Though I generally prefer

    char ch;
    while(infile.get(ch)) { ...

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Originally posted by grib
    To catch this you need: ...
    All of your examples will give the exact same results. The only way to work around an embedded EOF character in the middle of a text file is to use read(). And if you are on a Dos/Windows machine, you also have to open the file in binary mode or you'll never get past the embedded EOF.

    Text files aren't going to have embedded EOF charactars anyways.

    However, "while(infile.get(ch))" is better since it will stop the loop on eof() and any other fail() state that may occur.

    gg

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    From POSIX standard:
    If the integer value returned by fgetc() is stored into a variable of type char and then compared against the integer constant EOF, the comparison may never succeed, because sign-extension of a variable of type char on widening to integer is implementation-defined.
    So for maximum portability, use an int.

    gg

  6. #6
    bonnie
    Guest

    scrammbled

    replacing
    while ( ch != EOF )
    with
    while(infile.get(ch))
    made my data scrammbled like eggs?

  7. #7
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    Codeplug, note that the first version used a char, while the second used an int. Consider the following test program.
    Code:
    #include<iostream>
    #include<fstream>
    #include<ctype.h>
    
    using namespace std;
    
    void printquote(unsigned char c) {
    	char tbl[] = "0123456789ABCDEF";
    	if(isprint(c) || isspace(c)) {
    		cout << c;
    	} else {
    		cout << "\\0x" << tbl[(c>>4)&0x0F] << tbl[c & 0x0F];
    	}
    }
    
    int main() {
    	ofstream tmp("tmp",ios_base::trunc | ios_base::out);
    	tmp << (char)4 << " after unix eof char" << endl;	
    	tmp << (char)EOF << " after iostream's EOF" << endl;	
    	tmp << (char)26 << " after DOS eof char" << endl;	
    	tmp.close();
    	cout << "with char (in binary mode)" << endl;
    	{
    		ifstream in("tmp",ios_base::binary);
    		char ch;
    		while((ch=in.get())!=EOF) printquote(ch);
    	}
    	cout << "with int (in binary mode)" << endl;
    	{
    		ifstream in("tmp",ios_base::binary);
    		int ch;
    		while((ch=in.get())!=EOF) printquote(ch);
    	}
    	cout << "with iostream state (in text mode)" << endl;
    	{
    		ifstream in("tmp");
    		char ch;
    		while(in.get(ch)) printquote(ch);
    	}
    	return 0;
    }
    the printquote is needed, because sending the dos eof char to cout (under dos) results in wackyness, plus it's a lot easyer to read. The point is that in.get() is just as "aggresive" as read() when the file is in binary mode. Actually I am not sure what the point is but I spent so much time playing with the odd behaviour of sending ^z down cout it seems like a shame not to post.

    edit: possibly confusing this was not a reply to the OP scrambled posting.
    Last edited by grib; 04-04-2003 at 04:30 PM.

  8. #8
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    Originally posted by bonnie
    replacing
    while ( ch != EOF )
    with
    while(infile.get(ch))
    made my data scrammbled like eggs?
    Take note of CodePlug's previous comment, my guess is you still have too many infile.get()'s

    Code:
    char ch;
    while(infile.get(ch)) {
        cout << ch;
    }
    should output whatever file you opened with infile. Any more help and I might as well print it out and hand it in for you

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I bet you have ch as an int and are doing "cout << ch;" - change it back to a char.

    The point is that in.get() is just as "aggresive" as read() when the file is in binary mode.
    I was talking bout text mode.

    On dos/win machines, if a file is opened in text mode and contains an embedded eof (0x1a or 26), reading will stop there no matter what method you use (you can seek past it).

    I may have mis-spoke since I don't know if read() is more aggressive than get() on non-dos/win machines (linux box is down) with regards to an embedded eof (0x04 or 4), but I'd like to know. Both get() and read() may read it and keep going.

    gg

  10. #10
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    I'm not sure either, but the bug I was addressing in the case of
    char ch;
    while((ch = in.get())==EOF) ...
    does not primarally have to do with the eof character convention of the OS but (char)EOF appearing in the stream (as well as the postix issues you found). On Dos/Win (char)EOF == 0xFF. This get's passed regardless of the text/binary mode of the stream. In my tests read() on text mode streams stops on the dos eof(0x1A), just like get.

  11. #11
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Ahhh, wasn't looking at it like that - yes, that would bad for binary files (or text with an embedded 0xFF).

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  2. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  3. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  4. damn strings
    By jmzl666 in forum C Programming
    Replies: 10
    Last Post: 06-24-2002, 02:09 AM
  5. menus and strings
    By garycastillo in forum C Programming
    Replies: 3
    Last Post: 04-29-2002, 11:23 AM