random confusing error?

description of programs purpose:

i wanted to make a simple encryption program that you can drag a file onto the exe and it encrypts it and saves it with the same name with w/e extension i want on it.

however some pretty random stuff happens.
to list a few things going on.
1. the program works fine if run through the cmd line and given a simple file path like "test.file" that's in the same directory.
however heres where teh problem is.
when you drag a file onto it, it receives the full path "D:\My Documents\Visual Studio 2008\Projects\Levone Projects File Encryptor\LPFE quick and easy edition\test.file"

which is normally fine, but for some stupid reason i get some random ass errors.

here's the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

typedef unsigned long int Ulong;
typedef unsigned short int Ushort;

string mangle(string str, int method = 0)
{
	for(size_t i = 0; i < str.size(); i++)
	{
		switch(method)
		{
			case 1:
				str[i] = str[i] ^ 0xAA;
				break;
			case 2:
				str[i] = str[i] ^ 0x55;
				break;
			default:
				break;
		}
		str[i] = str[i] ^ 0xFF;
	}
	
	return str;
}

string GetExtension(char* cfilename)
{
	string sfilename;// String File Name, holds the filename in a std::string.
	string extension;// Holds the determined file extension
	int dotpos=0;// holds the position of the last dot.

	// This breaks the cfilename down so it can be stored in sfilename and eliminates possible NULL chars.
	for(int i = 0; cfilename[i] != 0; i++) 
		sfilename.push_back(cfilename[i]);

	// This is to find the position of the last '.' in the string
	for(size_t i = 0; i < sfilename.size(); i++)
	{
		if(sfilename[i] == '.')
			dotpos = i;
	}
	// checks to make sure there was a dot, otherwise there is no extension.
	if(dotpos != 0)
	{
		// Uses the dotposition to find the extension.
		for(size_t i = dotpos + 1; i < sfilename.size(); i++)
			extension.push_back(sfilename[i]);
	}

	return extension;
}

int main(int argc, char *argv[])
{
	//cout << argv[1];

	//check the argument count, print useage if incorrect.
	if(argc != 2)
	{
		cout << "useage" << argv[0] << " <filename>" << endl << endl;
		cout << "<filename> \t Path to file" << endl;
		return -1;
	}

	bool hasExt = false;
	bool completionflag = false;

	char ch;

	Ulong filesize = 0;
	Ulong placecount = 0;
	Ushort completed = 0;

	ifstream ifile;
	ofstream ofile;
	
	string filebuffer;
	string extension;
	extension = GetExtension(argv[1]);

	if(extension.empty() == false)
		hasExt = true;

	ifile.open(argv[1], ifstream.binary);
	if(ifile.fail())
	{
		cerr << "Failed to open " << argv[1] << endl;
		return -1;
	}

	char *path = new char[sizeof(argv[1]) + sizeof("enc")];
	sprintf(path, "%s.%s", argv[1], "lpfe");
	//cout << path << endl;
	ofile.open(path, ios::binary);
	if(ofile.fail())
	{
		cerr << "Failed to create intermediate file. "<< endl;
		return -1;
	}

	ifile.seekg(0, ios::end);
	filesize = static_cast <int> (ifile.tellg());
	ifile.seekg(0);

	for(Ulong i = 0; i < filesize + 1; i++)
	{
		Ushort temp = completed;

		if(i != 0)
			completed = (((float)i / (float)filesize) * (float)100);

		if(completed != temp)
			cout << completed << "% completed" << endl;
		
		if(ifile.get(ch) != NULL)
			filebuffer.push_back(ch);

		if(filebuffer.size() > (1024 * 1024 * 20) || (filebuffer.size() != NULL && i == filesize))
		{
			filebuffer = mangle(filebuffer, 1);
			for(size_t i = 0; i < filebuffer.size(); i++)
				ofile.put(filebuffer[i]);

			filebuffer.clear();
		}
	}
	ifile.close();
	ofile.close();

	return 0;
}


1.
when run in with my debugger, on line 100,
1
2
3
4
5
	if(ofile.fail())
	{
		cerr << "Failed to create intermediate file. "<< endl;
		return -1;
	}



turns true and it prints the error and exits.
it shouldn't even turn true.

when ran without the error, it throws an unhanded exception.

so im lost with WTF! going through my brain.

i hate random errors so please someone help me straighten this out.
Last edited on
i also want to note that if i skip the ofile opening check, it crashes with a bad alloc exeption or something when i reaches 32 and
1
2
 if(ifile.get(ch) != NULL)
			filebuffer.push_back(ch);


is called.
On lines 96 and 97 (line 96 is specially wrong, but I don't like 97, either) you're just asking for trouble. Put the strings into an std::string and use that to concatenate.
thanks.
so, i don't get it. why is it that something so simple fixed it?
can you explain to me what was going wrong.
i watched the variables and other things in the debugger for.. what... 2 days now?, and didn't see anything that should have caused a problem.
yet througing it in a std::string, which is esentialy almost the same as dynamically allocating a cstring (char array) and then passing the string as a c_str() fixed everything? WTF??!!

i love computers, computer science, but i fkn HATE how random they can be soemtimes.
(or at least what seems to me like randomness?)
Last edited on
sizeof(argv[1]) doesn't do what you think it does.
You think it'll give you 5 if the program was called with program hello, but in reality, you're asking for the size of a pointer (since argv is a char **, argv[i] is a char *). Usually, this will be 4 or perhaps 8, but it just won't give you the actual size of the string.
If you wanted to know the size of the string, you should have done strlen(argv[1]).

In any case, std::string exists so you don't have to waste your time with error-prone things like sprintf() or strcat(). You can use them if you really want to, but you're just making things harder for yourself. I used to do that, actually, until I got tired of debugging segmentation faults and realized it wasn't worth my time.

EDIT: Oh, and under normal conditions, computers are fully deterministic.
Last edited on
oh i see...

now that i think about it. i did do a check and the sizeof(argv[1]) returned 4...
didn't think to much into it tho, just figured it must have been a place holder or something.
well, thats the point of questions. :) good thing theres people like you who can set people like me straight.

thanks again helios.
Topic archived. No new replies allowed.