Help please

First off, I am completely new to C++. Currently I am in an online class (CS 161) and the teacher isn't very responsive. I'm not completely understanding everything 100% and am looking for some help/explanations. First I'll post the code that I have so far and then what the assignment is looking for to give you background. Here are the questions I have;

1. The assignment is telling me to use inFile.read(charArr, fileLen); to read the entire file into my char array, but I keep getting declaration errors no matter what I use (int, string, ifstream, etc). Am I missing something? Its currently not in my code at the moment due to the issues.

2. I am looking to make it so after it spits out the checksum, it returns to allow the user to the top of the selection screen (unless the selection was Q of course). I *think* I should use two functions for this, but anytime I try to separate the input/output and the opening of the file into separate functions, again errors.

3. Finally, when I do get a checksum its hexidecimal I think. Instead of a number it is spitting out 0038FCB4 on a text file given (can provide if needed). According to the example, it should just be a number.

Here is my code (its very basic, again I'm still learning and I am not looking for anyone to do my homework for me, just someone to point me in the correct direction..)

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
  #include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

// Declare Variables
char reply;

string filePath;




int main()
{
	const int SUM_ARR_SZ = 100;
	unsigned int checkSums[SUM_ARR_SZ];
	string fileNames[SUM_ARR_SZ];

	

	ifstream inFile;

	cout << "Please select: " << endl;
	cout << "A) Compute checksum of specified file " << endl;
	cout << "B) Verify integrity of specified file " << endl;
	cout << "Q) Quit " << endl;
	cin >> reply;

		switch (reply)
		{
		case'A':
		case'a':
			cout << "Specify the file path: " << endl;
			cin >> filePath;
			break;
		case'B':
		case'b':
			cout << "Specify the file path: " << endl;
			cin >> filePath;
			break;
		case'Q':
		case'q':
			break;
		default:
			cout << "Invalid Input." << endl;

		}

	inFile.open(filePath.c_str(), ios::binary);
	inFile.seekg(0, ios_base::end);
	int fileLen = inFile.tellg();
	inFile.seekg(0, ios_base::beg);
	

	cout << "File checksum = " << checkSums << endl;

	inFile.close();

	inFile.clear(std::ios_base::goodbit);

	system("pause");
	return 0;
	
}



Here is the assignment. Thank you.

Your assignment is to write a C++ program which will automatically compute the checksum on a specified data file, and then store that checksum in an unsigned integer array. The program must also store the file name in another, parallel array. You can use these declarations in your program:

const int SUM_ARR_SZ = 100;
unsigned int checkSums[SUM_ARR_SZ];
string fileNames[SUM_ARR_SZ];

This gives your program the flexibility to run checksums on several files (up to 100) and remember which sums go with which files.

Your program should then be able to verify that a specified file has not been compromised by running the checksum over it and verifying that the checksum is what it was previously.

Your program *must* read the file into a char array. Make the array size 100000 chars so that it is large enough for our file. After the file is stored in the array, your program must loop through the array to compute the checksum using the algorithm described above (simple sum).

Since this is essentially an operation on a binary file (even though text may be stored in the file), open the file in binary mode to prevent the system from performing any interpretation on the data like this:

inFile.open(filePath.c_str(), ios::binary);


To get the file size, use the seekg and tellg operators like this:

inFile.seekg(0, ios_base::end);
int fileLen = inFile.tellg();
inFile.seekg(0, ios_base::beg);


The first line moves the file cursor to the end of the file. The second line reads the byte position at that current location. The third statement moves the file cursor back to the beginning of the file so the data can be read from the beginning.

After that, you can read the entire file contents into your char array in one statement like this:

inFile.read(charArr, fileLen);

Then the file must be closed:

inFile.close();

The following line seems to be required to put the file back to a state where it can be opened again it (otherwise, some compilers, like mine, will not allow the file to be reopened):

inFile.clear(std::ios_base::goodbit);

For comparing file names, use the strcmp() built in function.

High level pseudocode for determining the checksum may look something like this:

1. Open the specified file in binary mode
2. Save the file name in the fileNames array.
3. Determine the file size using seekg and tellg
4. Read the file contents into the character array in one statement
5. Close the file
6. Loop through the array, one character at a time and accumulate the sum of each byte
7. Store the sum into the checkSums array.

Sample Dialog:
Note: In the example below, the user’s input is in RED BOLD. The program output is not. Also, your code should allow menu entry input in a case insensitive manner.

Please select:
A) Compute checksum of specified file
B) Verify integrity of specified file
Q) Quit
a
Specify the file path: c:\temp\tmp1
File checksum = 1530
Please select:
A) Compute checksum of specified file
B) Verify integrity of specified file
Q) Quit
a
Specify the file path: c:\temp\tmp2
File checksum = 29430
Please select:
A) Compute checksum of specified file
B) Verify integrity of specified file
Q) Quit
b
Specify the file path: c:\temp\tmp1
File checksum = 1530
The file integrity check has passed successfully (checksum = 0).

Please select:
A) Compute checksum of specified file
B) Verify integrity of specified file
Q) Quit
b
Specify the file path: c:\temp\tmp1
File checksum = 1597
The file integrity check has failed (previous checksum = 1530, new checksum = 1597)

Please select:
A) Compute checksum of specified file
B) Verify integrity of specified file
Q) Quit
b
Specify the file path: c:\temp\tmp3
File checksum = 5596
The checksum has not been computed on the file: c:\temp\tmp3
Please select:
A) Compute checksum of specified file
B) Verify integrity of specified file
Q) Quit
Last edited on
I keep getting declaration errors no matter what I use
Exactly what error do you get? BTW correct way to read binary is this:
1
2
3
4
5
6
7
8
9
10
11
12
//"Your program *must* read the file into a char array. Make the array size 100000 chars"
char charArr[100000];

//std::ifstream inFile(filePath, std::ios::binary); 

//"To get the file size, use the seekg and tellg operators like this:"
inFile.seekg(0, ios_base::end);
int fileLen = inFile.tellg();
inFile.seekg(0, ios_base::beg);

//"After that, you can read the entire file contents into your char array in one statement like this:"
inFile.read(charArr, fileLen);


I *think* I should use two functions for this
It would be a good idea: separating code in logical blocks, avoiding huge monolitic functions and allowing to inctroduce loop for main menu more easily. Also verify integrity function will be simple: it just calls compute checksum and then compares it to previous value.


Finally, when I do get a checksum its hexidecimal I think. Instead of a number it is spitting out 0038FCB4 on a text file given (can provide if needed).
How do you clculate and print it?
Thank you on that char charArr part. I was forgetting the [100000] part.

I was able to get it into two functions now and working on that part, so that is good. However I don't know how to compare it to a previous value.

As for the calculate part, I am not sure how to answer it. After declaring unsigned int checkSums[SUM_ARR_SZ] as stated in the assignment, then couting checkSums is when I get the hexidecimal output.

Also one more thing to add. I am trying to do the do...while, but I can't seem to get it to stop if q or Q is present. What am I doing wrong? Update code is below;

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
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

// Declare Variables
char reply;

string filePath;

void openFile();


int main()
{
	do
	{
		cout << "Please select: " << endl;
		cout << "A) Compute checksum of specified file " << endl;
		cout << "B) Verify integrity of specified file " << endl;
		cout << "Q) Quit " << endl;
		cin >> reply;

		switch (reply)
		{
		case'A':
		case'a':
			cout << "Specify the file path: " << endl;
			cin >> filePath;
			openFile();
			break;
		case'B':
		case'b':
			cout << "Specify the file path: " << endl;
			cin >> filePath;
			openFile();
			break;
		case'Q':
		case'q':
			break;
		default:
			cout << "Invalid Input." << endl;
			break;

		}
	} while (reply != 'Q' || reply != 'q');
		
	system("pause");
	return 0;
	
}

void openFile()
{

	const int SUM_ARR_SZ = 100;
	unsigned int checkSums[SUM_ARR_SZ];
	string fileNames[SUM_ARR_SZ];

	char charArr[100000];

	ifstream inFile;

	inFile.open(filePath.c_str(), ios::binary);
	inFile.seekg(0, ios_base::end);
	int fileLen = inFile.tellg();
	inFile.seekg(0, ios_base::beg);

	inFile.read(charArr, fileLen);

	cout << "File checksum = " << checkSums << endl;

	inFile.close();

	inFile.clear(std::ios_base::goodbit);

}

However I don't know how to compare it to a previous value.

Store checksums in main function. calculate_checksum should only return value which you will store in corresponding cell. verify_checksum should take expected checksum as parameter and you will just need to compare it with it.

After declaring unsigned int checkSums[SUM_ARR_SZ] as stated in the assignment, then couting checkSums is when I get the hexidecimal output.
Do you use std::hex manipulator somewhere? It is persistent: once it is set, it stays that way unless you explicitely turn it off.

I can't seem to get it to stop if q or Q is present. What am I doing wrong?
You need and instead of or in loop condition.
Rigth now it reads continue looping as long as choice is not 'Q' or it is not 'q', which is always true: if choice is 'Q' it is certainly is not 'q' and vice versa.
I am not using std::hex anywhere. What you see is what I have exactly. As for the loop all I can say is 'DOH!'....
Could you also elaborate on the checksum portion? I'm not understanding exactly. Are you saying that I should move my inFile.read to the main function? Also about the calculate and verify. Thank you for your help.
Last edited on
checkSums is an array, not a single variable. When you try to print it (instead of printing some element) it decays to pointer and pointers are printed in hex.
I'm sorry. I'm still lost. I'll go through my book again on arrays and printing it, it seems almost over my head. This is supposed to be Intro to C++ and I'm still having a hard time.
Could you also elaborate on the checksum portion?
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
//This function opens file and returns it checksum
unsigned calculate_checksum(const std::string& filename);

bool verify_checksum(const std::string& filename, unsigned checksum)
{
    //returns whether calculated checksum is same as expected
    if(checksum == calculate_checksum(filename))
        return true;
    else
        return false;
}

/*...*/

        switch (reply) {
        case'a':
            cout << "Specify the file path: " << endl;
            cin >> filePath;
            //There should be calculations to figure out where to put checksum result
            checkSums[0] = calculate_checksum(filePath);
            break;
        case'b':
            cout << "Specify the file path: " << endl;
            cin >> filePath;
            //There is a check to figure out which checksum belongs to file
            if(verify_checksum(filePath, checkSums[/*...*/]))
                std::cout << "correct\n";
            else
                std::cout << "invalid'n";
            
            break;
        case'q':
            break;
        default:
            cout << "Invalid Input." << endl;
            break;

        }


EDIT:
I'm sorry. I'm still lost
1
2
3
int foo[2] = {1, 2};
std::cout << foo << '\n'; //prints address of an array
std::cout << foo[0] << '\n' //prints value of first element
0x7fffedd3da78
1
http://coliru.stacked-crooked.com/a/b52a5f508c6e4dde
Last edited on
Ah ha! Thanks on that example for the printing of the address. I didn't have the [*] portion when trying cout it. That made a whole difference.

One last question;

Can I call a value from another function into a different one as long as its delcared?

i.e. cout << valueFunction1 << valueCurrentFunction

If that makes any sense?
I am not sure what are you asking, but you can chain function calls:
1
2
3
4
int five() { return 5; }
int addtwo(int x) {return x + 2;}
//...
std::cout << addtwo(five()); //7 

and you can call functions from functions
1
2
3
4
int foo() {return 1;}
int bar() {return foo() + 2; }
//...
std::cout << foo() << bar(); //13 
I have a void openFile() function that reads the checksum value and stores it into checkSums[SUM_ARR_SZ]. Then when the user presses b to verify, it goes to a void verifyFile() function. Within that one I want to pull the checksum value from the openFile() function to check to see if its the same or not. Depending on the results is depending on what the switch does.
If your checkSums is contained inside openFile function (it shouldn't), then you cannot access it. To get value from function, return it. I have wrote rough skeleton of program in earlier post.
Hmm. I tried adding all of that from your earlier post, but the compiler was still giving me errors. So I sort of starting going off the deep end and trying different things. I am probably way off base now. It is now returning negative values for the checksum and even if I give it a different filepath for the verification peice, it still says its the same and has passed.

I'll go back to your earlier post and try again to see if I missed anything. Here is what I have right now. (its a mess...I know..)

Last edited on
Back to square one. I still get compiler errors on what you posted earlier..

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
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

// Declare Variables
char reply;

string filePath;
string calculate_checksum(filePath);

int checksum;




int main()
{

	

	const int SUM_ARR_SZ = 100;
	unsigned int checkSums[SUM_ARR_SZ];
	string fileNames[SUM_ARR_SZ];

	char charArr[100000];

	ifstream inFile;

	//inFile.open(filePath.c_str(), ios::binary);
	inFile.seekg(0, ios_base::end);
	int fileLen = inFile.tellg();
	inFile.seekg(0, ios_base::beg);

	inFile.read(charArr, fileLen);


	inFile.close();

	inFile.clear(std::ios_base::goodbit);
	
	do
	{
		cout << "Please select: " << endl;
		cout << "A) Compute checksum of specified file " << endl;
		cout << "B) Verify integrity of specified file " << endl;
		cout << "Q) Quit " << endl;
		cin >> reply;


		switch (reply)
		{
		case'A':
		case'a':
			cout << "Specify the file path: ";
			cin >> filePath;
			cout << "File checksum = " << checkSums[0] << endl;
			break;
		case'B':
		case'b':
			cout << "Specify the file path: ";
			cin >> filePath;
			
			if (checkSums[0] == checkSums[0])
			{
				cout << "The file integrity check has passed successfully (checksum = " << checkSums[0] << endl;

			}

			else
			{
				cout << "The file integrity check has failed (previous checksum = " << checkSums[0] << ", new checksums = " << checkSums[0] << ") " << endl;
			}
			
			break;
		case'Q':
		case'q':
			break;
		default:
			cout << "Invalid Input." << endl;
			break;

		}
	} while (reply != 'Q' && reply != 'q');
		
	system("pause");
	return 0;
	
}
Can you post the errors?
If I just even add this portion;

1
2
3
4
5
6
7
8
9
10
unsigned calculate_checksum(const std::string& filename);

bool verify_checksum(const std::string& filename, unsigned checksum)
{
    //returns whether calculated checksum is same as expected
    if(checksum == calculate_checksum(filename))
        return true;
    else
        return false;
}


I get these errors

Warning 1 warning C4244: 'initializing' : conversion from 'std::streamoff' to 'int', possible loss of data c:\users\edward\desktop\ed's school stuff\c++\assignment 6\main.cpp 39 1 Assignment 6

Error 2 error C2365: 'calculate_checksum' : redefinition; previous definition was 'data variable' c:\users\edward\desktop\ed's school stuff\c++\assignment 6\main.cpp 98 1 Assignment 6

Error 3 error C2064: term does not evaluate to a function taking 1 arguments c:\users\edward\desktop\ed's school stuff\c++\assignment 6\main.cpp 103 1 Assignment 6

4 IntelliSense: declaration is incompatible with "unsigned int calculate_checksum(const std::string &filename)" (declared at line 98) c:\Users\Edward\Desktop\Ed's School Stuff\C++\Assignment 6\main.cpp 17 8 Assignment 6

5 IntelliSense: declaration is incompatible with "std::string calculate_checksum" (declared at line 17) c:\Users\Edward\Desktop\Ed's School Stuff\C++\Assignment 6\main.cpp 98 10 Assignment 6
Also I know that I am supposed to save the file name into the fileNames array and store the sum into the checkSums array, am I actually even doing that?

High level pseudocode for determining the checksum may look something like this:

1. Open the specified file in binary mode
2. Save the file name in the fileNames array.
3. Determine the file size using seekg and tellg
4. Read the file contents into the character array in one statement
5. Close the file
6. Loop through the array, one character at a time and accumulate the sum of each byte
7. Store the sum into the checkSums array.

Last edited on
Topic archived. No new replies allowed.