Reading hexadecimal from file and converting to integers

So my assignment is to read an unknown amount of hexadecimal numbers from a file into a char array, create a function to convert it to regular numbers, and then add up all the numbers.

If that isn't clear, here is the assignment: http://www.cs.csi.cuny.edu/~zelikovi/csc211/Lab1.htm

In the file right now is "45AF 12B3" and the correct answer is 22626.

The long calculation at the bottom of the code gets the right answer, but it doesn't work if I change the content of the file.

The if statements in the loop don't come out to the right answer. Also, if I use the power function there I get errors telling me I can't convert a double to an int.

Thanks in advance to anybody that takes the time to look this over.

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

using namespace std;

const int ALPHA = 25, BETA = 4;

int convert(int, int, char[ALPHA][BETA]);

int main()
{
	int i, j, sum = 0;
	char hex[ALPHA][BETA];
	int integer[ALPHA][BETA];

	ifstream myFile;
	myFile.open("C:/Users/AJS/Documents/School/Summer 2017/CSC 211/Lab 3/hex.dat");

	if (!myFile)
		cout << "ERROR\n\n";

	while (!myFile.eof())
	{
		for (i = 0; i <= ALPHA - 1; i++)
			for (j = 0; j <= BETA - 1; j++)
			{
				myFile >> hex[i][j];

				integer[i][j] = convert(i, j, hex);

				//running sum that doesn't compute correctly
				if (j == 0)
					sum += (convert(i, j, hex) * 16 * 16 * 16);
				else if (j == 1)
					sum += (convert(i, j, hex) * 16 * 16);
				else if (j == 2)
					sum += (convert(i, j, hex) * 16);
				else if (j == 3)
					sum += convert(i, j, hex);
			}
	}
		
	cout << hex[0][0] << hex[0][1] << hex[0][2] << hex[0][3] << endl;
	cout << hex[1][0] << hex[1][1] << hex[1][2] << hex[1][3] << endl;

	cout << sum << endl;

	cout << (integer[0][0] * pow(16, 3)) + (integer[0][1] * pow(16, 2)) + (integer[0][2] * pow(16, 1)) + (integer[0][3] * pow(16, 0)) + (integer[1][0] * pow(16, 3)) + (integer[1][1] * pow(16, 2)) + (integer[1][2] * pow(16, 1)) + (integer[1][3] * pow(16, 0)) << endl;
	myFile.close();
	
	return 0;
}

int convert(int m, int n, char hexadecimal[ALPHA][BETA])
{
	switch (hexadecimal[m][n])
	{
		case '0': return 0; break;
		case '1': return 1; break;
		case '2': return 2; break;
		case '3': return 3; break;
		case '4': return 4; break;
		case '5': return 5; break;
		case '6': return 6; break;
		case '7': return 7; break;
		case '8': return 8; break;
		case '9': return 9; break;
		case 'A':
		case 'a': return 10; break;
		case 'B':
		case 'b': return 11; break;
		case 'C':
		case 'c': return 12; break;
		case 'D':
		case 'd': return 13; break;
		case 'E':
		case 'e': return 14; break;
		case 'F':
		case 'f': return 15; break;
	}
}
Last edited on
closed account (1vf9z8AR)
i dont exactly remeber the conversion but let me tell you the code isnt this long.Always try to use simple codes.
hope this link helps~http://lmgtfy.com/?q=hexadecimal+to+integer+c%2B%2B
Last edited on
Your code looks too complicated. The assignment doesn't say that you have to store all the numbers. You need one var total and when you have read a number and converted it just add it to total.
Something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int HexStrToInt(char str[])
{
  // your conversion here
  // return converted number
}

int main()
{
  ifstream src("numbers.txt");
  if (!src)
  {
    // some error msg 
    return -1;
  }
  char buf[5] = {0};
  src.width(5);
  int total = 0;
  while (src >> buf)
  {
    int num = HexStrToInt(buf);
    total += num;
  }
  // show total
}
The conversion and subsequent addition to a sum is where I'm having most trouble. I tried to multiply the conversation to the right 16th power within the function based on which digit it is, but I have problems when I use switch statements in if statements, and so I came up with what I have below but it doesn't get the right answer

1
2
3
4
5
6
7
8
if (j == 0)
	sum += (convert(i, j, hex) * 16 * 16 * 16);
else if (j == 1)
	sum += (convert(i, j, hex) * 16 * 16);
else if (j == 2)
	sum += (convert(i, j, hex) * 16);
else if (j == 3)
	sum += convert(i, j, hex);


I don't understand what this is:

while (src >> buf)
Last edited on
while (src >> buf)
This is the idiomatic read-loop as it appears in C++.

Assuming src is an input stream of some sort, the expression (src >> buf) can be converted to a bool. The result of that conversion is true if and only if the read was successful. Otherwise the result is false.

The idea is that you read a single element in the loop header and process that element in the middle of the loop. In this case, it is a replacement for the pattern while (!myFile.eof()) { myFile << x; }, which is blatantly wrong.
Last edited on
How do I use the idiomatic read-loop? If what I'm using is blatantly wrong please help me understand.

What is the fist element it reads? Is it just a single character or a line? I would love to test this and learn but I don't know how to use it.

What specifically is the bool converting from?
Last edited on
Try to run this code in a main function and look at the output. Hopefully things are clear then.
1
2
3
4
5
6
7
8
9
10
11
12
13
ifstream src("numbers.txt");
  if (!src)
  {
    // some error msg 
    return -1;
  }
  char buf[5] = {0}; // 4 hex digits + '\0' - assumes 32 bit sytem where an int has max 4 hex-digits
  src.width(5); 
  int total = 0;
  while (src >> buf) // will read up to 4 characters(stops at a whitespace) + terminating '\0' int buf
  {
     cout << buf << "\n";
  }

What specifically is the bool converting from?

There's a lot going on:

Think about this statement for a moment:
std::cout << "hello" << ' ' << "world\n";
If you go to your favorite reference page (e.g. http://en.cppreference.com/w/cpp/language/operator_precedence ) and look up the associativity of the operator<<, you'll find that it is left-associative, and so the statement above is semantically equivalent to
(((std::cout << "hello") << ' ') << "world\n");

In order to get this to print "hello", then a space, then "world", the result of (std::cout << "hello") must be std::cout itself, or at least look like it. That implies that ((std::cout << "hello") << ' ') is similarly std::cout itself, or close, and the entire full-expression (((std::cout << "hello") << ' ') << "world\n") is also std::cout.

The same idea is applied to all other streams, too, no matter which way the arrows face, or what the names are. This includes src in your code above: (src >> buf) results in src itself, or something close to it.

This technique is called "method chaining", and the point of this is to show that for any stream - std::cin, any std::istream, std::ifstream, std::cout, std::ostream, std::ofstream, etc.: the expressions
input_stream >> variable; and
output_stream << variable
result in input_stream and output_stream respectively.

Every stream has an error state, and can be converted into a bool. If the stream is in an error state, then an I/O operation upon the stream does nothing and returns the stream.
If the stream is not in an error state, then an I/O operation upon the stream is attempted. If and only if the I/O operation fails, the stream's error state is set. Then, the stream is returned.

When the stream is converted to bool, the result is true if and only if the stream is not in an error state. Otherwise, the result is false.

In the loop
while (src >> buf),
The expression (src >> buf) is used as a boolean condition. If the stream state is good, the read is attempted and if it is successful, buf is given the new value, and the loop runs. If the stream state is not good, the read is never attempted and the loop never runs.

Unlike while (!str.eof()), the condition above will not result in processing the last element twice, nor will it enter an infinite loop if the read operation fails due to something other than the end-of-file being reached.
Last edited on
The conversion and subsequent addition to a sum is where I'm having most trouble.

What do you want, the solution or hints?
Let’s start from Thomas1965 code, where it is supposed to exists a function
int HexStrToInt(char*)

Assuming you pass a char* parameter called “buf”, that function should work more or less that way:
- there should be a variable which holds the return value;
- there should be a loop that:
- start from the *last but one* character in “buf”;
- evaluate that character in a switch;
- increment the return value by: a number decided by the value of the character being evaluated * pow(16, an exponent that increases every time a new character is evaluated);
- then, the following character from “buf” should be evaluated, going from right to left (i.e. by a decreasing index).

I can’t be clearer in my poor English, but I can give you the working code if needed.
Happy coding!
Last edited on
The conversion and subsequent addition to a sum is where I'm having most trouble.

That's because you're trying to convert the input AND accumulate the sum one digit at a time. That's unnecessary, difficult, and isn't what the assignment calls for:
b) convert the character arrays to numbers (by calling a function that takes the character array as a parameter, and returns an integer)
c) add the numbers to get a decimal sum

So you're supposed to convert the arrays to numbers. After fully converting the arrays to numbers, you're supposed to add the resulting numbers to produce a sum.

int convert(int m, int n, char hexadecimal[ALPHA][BETA])
This function does works, but it can only ever be used to convert a character from a 2 dimensional char array of ALPHA x BETA characters. It would be better to make this more general by having int convert any character
1
2
3
4
5
int convert(char ch)
{
    switch (ch) {
...
}


Using this, you can write Thomas1965's HexStrToInt() function to convert an entire string to an integer.

Test your HexStrToInt() function. Write a main() program that reads a hex string from cin, converts it to an int, and prints the int to cout.

Now you're 95% of the way there. Modify the program to read two strings, convert them both, add the result and print it out.

Next, do part 2: assume the input has an unknown number of strings and read/add them all.

Finally, if you're up to it, do the extra credit part: write a function that converts an int to a hex string. Modify your program to convert the sum to the hex string and print it out.
Topic archived. No new replies allowed.