Click to See Complete Forum and Search --> : messed up terminal after shifting characters


orufet
09-05-2004, 05:18 AM
Right. So, I'm writing a program that reads text from a file, encryptions it (just by shifting the characters over one) and writes to a new file. The problem is, however, that once the program is finished running, my terminal seems to be encryped as well...

I'm not an experienced programmer, but I know that my code worked at some point. Perhaps you guys could figure this one out?

Here's the main function:


int opendecfile() {
char path[256];
char newpath[256];
int confirm=0;
int buf=0;
const int BUF_MAX=512;

// open a normal file to be encrypted
while(confirm==0) {
cout << "\nPlease type the full path of the file: ";
cin >> path;
cout << "\nThe file you chose to encrypt is " << path;
cout << "\nIs this correct? [y=1/n=0] ";
cin >> confirm;
if(confirm==1) {
// they got the path right
break;
}

}
cout << "\nEncrypting file " << path << "\n";

// open the file for reading and encrypt it as we go

ifstream decfile(path);
char buffer[BUF_MAX];
if(!decfile.is_open()) {
cout << "\nError opening file...\n";
exit(1);
}

cout << "Please type the name of the new file: ";
cin >> newpath;

cout << "New file contents:";
cout << "\n\n---\n\n";

ofstream encfile(newpath); // the file to which we're writing

while(!decfile.eof()) {
decfile.getline(buffer,100);
for(buf=0;buf<=strlen(buffer);buf++) {
// strcpy(buffer,buffer);
// modify each character
buffer[buf]=buffer[buf]-1;
// cout << buffer[buf];
}
cout << buffer << endl;

// write encrypted file
if(encfile.is_open()) {
encfile << buffer;

}
// cout << endl;

}

encfile.close();
decfile.close();
cout << "\n\n---\n\n";

cout << "Done encrypting!\n";

// delete original file


return 0;
}


And a paste of the output:


New file contents:

---

gdkkn+sghrhr`sdrsnelxdmbqxoshnmoqnfq`l�?┘ÿ ÿÿÿÿÿÿÿÿóþ¾V9␋ÿá…┐ÿº␌_ÿ┬j��������������k��7k�߱j�/�
i������������U8h���j��b��v␋þþþþþþþþþþþþ¢…┘þþ6┘þÞ °␋þ.³ÿ?ÿÿÿK·
␤ýýýýýýýýýýýý¡„␋ýý5␋ýݯ␤ý-²þ>þþþJ¶ÿ?§¸⎺┌␍⎺^┘ý=Ý ␤ýýýýýýýýýñü¼T7±ý߃␋ý¸▒«ý┤

│├␊⎼└
---

D⎺┼␊ ␊┼␌⎼≤⎻├␋┼±!
[┘▒␌⎺␉@S0106000802°46␍␊8 ⎽⎼␌]$ │├␊⎼└



I hope the error was stupid and obvious...thanks

bryan.6
09-05-2004, 09:55 AM
i don't know the solution to your programming problem, but a solution for you until you get it figured out is to type 'setterm -reset' (or maybe 'setterm --reset', i'm not by a linux box so i can't be sure). that will return your terminal to an 'unencrypted' state.

mwinterberg
09-05-2004, 01:10 PM
Originally posted by orufet
decfile.getline(buffer,100);
for(buf=0;buf<=strlen(buffer);buf++) {
// strcpy(buffer,buffer);
// modify each character
buffer[buf]=buffer[buf]-1;
// cout << buffer[buf];
}

There are three things wrong with this.
One: strlen does not include the NULL terminator in it's count of the length of the string, so if you read in 5 characters, buffer will have:
"asdf\0junkjunkjunkjunkjunketc..." and you'll be modifying the \0 to be (char)255 (assuming char is unsigned). This means that buffer will no longer be null terminated when you output that text, both to cout and to encfile (there's also another problem I just realized with this, see below).

The second thing is, what if the line you're reading in is 150 characters long? buffer won't be null terminated at all, so strlen will start reading memory past the length of buffer. And then you'll start reading and writing pass that buffer.

The last thing is, since you're modifying the null terminator, how will strlen behave?
Let's say that this is buffer:
[ 'a', 's', 'd', 'f', '\0']
strlen will return 4. after the first four iterations of your for loop, it'll be:
[ '`', 'r', 'c', 'e', '\0']
strlen will still return 4. Your <= says to go on when buf == 4, so your code will dutifully go onto the next (NULL), character:
[ '`', 'r', 'c', 'e', 'ÿ', 'j', 'u', 'n', 'k', 'd', 'a', 't', 'a']
Now strlen will behave the same way as in the second case. Since you're modifying buffer, it'd be a bad optimization if your compiler optimized the call to strlen out in the for loop test as there are perfectly legitimate cases where that would be unintentional, and impossible for the writer of the code to get the intended behavior except with some compiler flags.

But, what bryan.6 said is neat. I'll have to remember that again for when that happens to me.

bwkaz
09-05-2004, 02:13 PM
Your terminal is broken because you've tried to output a bunch of non-printable characters, and one of them put the terminal into its second mode (the one where normal character bytes get printed as graphics characters).

The reason for this may be the null-termination mentioned earlier (if you try to print out past the end of a buffer, you'll print random bytes until you happen to hit a 0 byte).