C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old July 12th, 2003, 11:14 AM
holguie81 holguie81 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2003
Posts: 4 holguie81 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Binary to Decimal

I am currently unrolled in a introductory C++ class and I just don't get this assignment can some one please help me.

Write a program that reads characters representing binary (base-2) from a data file and translates them to decimal base (base-10) numbers the binary and decimal numbers should be out put in two columns with appropriate headings here is a sample of the out put:

Binary Number Decimal Equivalent
1 1
10 2
11 3
10000 16
10101 21

There is only one binary number per input line, but an arbitrary number of blanks can precede the number. The program must read the binary numbers one character at a time. As each character is read, the program multiplies the total decimal value by 2 and adds either 1 0r 0, depending on the input character. The program should check for bad data; if it encounters any thing except a 0 or a 1, it should out put the message "Bad digit on input."

I am to the point where my program can get the character one at time (left to right). I understand how to do the math but I just can't figure out how to assign the pow() since the program is reading the characters left to right.

This is what I have so far I hope I am on the right track.

#include <iostream>
#include <fstream> // For file I/O
#include <string> // For sting data type

using namespace std;

int main()
{

ifstream inFile; // Data file


// Promts the user for a file name.

string fileName; // File name
string binary;
char currentChar;
int newChar0;
int newChar1;
int loopCount;

cout << "Input file name: ";
cin >> fileName;
cout << "\n";

// Opens the File.

inFile.open(fileName.c_str()); // Changes variable into a C string and opens the file.
if (!inFile) // Checks to see if the file was opened.
{
cout << "*** Can't open input file ***\n\n"; // If file not opened
return 1;
}

//

cout << "\nBinary Number\tDecimal Equivalent\n";

inFile.get(currentChar);
newChar0 = 0;
newChar1 = 1;
loopCount = 0;
while (inFile)
{

if (currentChar < 48 || currentChar > 49)
{
cout << "bad digit input\n";
return 1;
}

if (currentChar == 48 || currentChar == 49)
{
loopCount++;
}

if (currentChar == 48)
{
newChar0 = currentChar;
}

if (currentChar == 49)
{
newChar1 = currentChar;
}

cout << currentChar;






inFile.get(currentChar);
}

cout << "\n" << loopCount << "\n";

return 0;
}

Reply With Quote
  #2  
Old July 12th, 2003, 12:10 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Click here for more information.
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,717 Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Days 12 h 28 m 46 sec
Reputation Power: 1179
Here you go... You didn't have code to handle leading spaces, so I took the liberty of adding that as well. I've commented the code quite a bit, so I hope the logic is easy to follow.
Code:
#include <iostream>
#include <fstream> // For File I/O
#include <string>

using namespace std;

bool validate_line(string s);
int  bin_to_dec(string s);
void pretty_print_line(string s);

int main(void) 
{
  ifstream inFile; // Data file

  // Promts the user for a file name. 
  string fileName; // File name 
  string binary; 

  cout << "Input file name: "; 
  cin >> fileName; 

  // Opens the File. 
  inFile.open(fileName.c_str()); // Changes variable into a C string and opens the file. 
  if (!inFile.good()) {
    cerr << "Could not open " << fileName << endl << endl;
    return 1;
  }

  cout << endl << "Binary Number\tDecimal Equivalent" << endl; 

  while (!inFile.eof()) {
    string s_line;
    getline(inFile, s_line); // Read a complete line.

    if (!inFile.eof()) {
      // Now make sure there are no invalid characters.
      if (!validate_line(s_line)) {
        cerr << "Line " << s_line << " contains invalid characters! " << endl;
      } else {      
         // Compute the result
         pretty_print_line(s_line);
         cout << "\t\t" << bin_to_dec(s_line) << endl;
      }
    }
  }

  return 0;
}

bool validate_line(string s) 
{
  const char *ptr;
  
  // Go through the string and check for invalid chararacters
  for (ptr = s.c_str(); *ptr; ptr++) 
    if (*ptr != '0' && *ptr != '1' && *ptr != ' ') // Spaces are valid chars
      return false;
  
  return true;
}

int bin_to_dec(string s) 
{
  int n_len = s.size(); // Compute initial length of string;
  int n_count = 0;
  int n_pow;
  int n_retval = 0;

  // First eliminate the leading spaces before the line
  for (int i = 0; i < s.size(); i++, n_count++)
    if (s[i] != ' ')
      break;

  // Now compute the actual string length (minus the leading spaces)
  n_len -= n_count;

  // Now compute the multiplying factor
  n_pow = 1 << (n_len - 1);

  // Now compute the result
  char ch;
  for (int i = n_count; i < s.size(); i++) {
    ch = s[i];     // Get the char at position i
    if (ch == '1') // If the char is '1' ....
      n_retval += n_pow; // ... add power of 2 to it (n_pow * 1 = n_pow)

    n_pow >>= 1; // Divide multiplying factor by 2 each time
  }
  return n_retval;
}

void pretty_print_line(string s) 
{
  // Print the line without the leading spaces
  for (int i = 0; i < s.size(); i++) 
    if (s[i] != ' ')
      cout << s[i];
}


This was the input file I tested with
Code:
        1
       10a
     1001
1100
1101
10001

Just out of curiosity, which school do you go to?

Last edited by Scorpions4ever : July 12th, 2003 at 12:13 PM.

Reply With Quote
  #3  
Old July 12th, 2003, 02:01 PM
holguie81 holguie81 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2003
Posts: 4 holguie81 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
I just tried to compile your code and I got this:

1 sample.cpp(82) : error C2374: 'i' : redefinition; multiple initialization

For this line:

for (int i = n_count; i < s.size(); i++)

I still haven't gone through it to understand the code yet so that’s what I am going to do next, but I really appreciate your help with this because I was totally lost.

Oh before I forget I go to the University of Maryland Community College. Thanks again!

Reply With Quote
  #4  
Old July 12th, 2003, 02:07 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Click here for more information.
 
Join Date: Nov 2001
Location: Glendale, Los Angeles County, California, USA
Posts: 7,717 Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 3rd Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Days 12 h 28 m 46 sec
Reputation Power: 1179
Bet you're using a mouldy old compiler like Borland C++ 3.0 or 4.0. The problem is, I used a loop variable 'i' a few lines above:
// First eliminate the leading spaces before the line
for (int i = 0; i < s.size(); i++, n_count++)

and then I used it again here:
for (int i = n_count; i < s.size(); i++)

The C++ standard says that this is perfectly valid, since 'i' will only have scope inside the loop. However, older C++ compilers didn't always do this. Instead, the first time you declared the variable, they would keep the scope for the rest of the function, instead of within the loop block alone. Hence, the compiler is complaining that 'i' was already declared. Go ahead and change the second loop variable to something else like 'j' and it should work fine.

Reply With Quote
  #5  
Old July 13th, 2003, 12:38 AM
messorian messorian is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2003
Location: NY
Posts: 18 messorian User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 2 h 34 m 18 sec
Reputation Power: 0
Ok, it's late at night and I love little programming exercises like this The following code should also work, the cool thing about this though, is that it takes advantage of C's binary operators to create the correct value. In the code, you will see the use of <<, this represents a left binary shift and moves given value the specified number of bits left. So given the binary value 1001, shifting it one to the left would produce 10010. Also, I use the | operator. This is a binary OR operator and is used to return all the 1's from two values. So, given 10010, ORing that with 1 would produce 10011. Anyway, hopefully you will be able to read through and figure out whats going on. Also, I provided a link that will hopefully be a bit more clear about the OR operator than I was.

Boolean Logic

--messorian

Code:
// binarytoint.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char* argv[]) {
	ifstream inFile; // Data file

	// Promts the user for a file name. 
	string fileName; // File name 
	string binary; 

	cout << "Input file name: "; 
	cin >> fileName; 

	// open the file
	inFile.open(fileName.c_str() );

	// make sure the file is valid
	if (!inFile.good()) {
		cerr << "Could not open file: " << fileName << endl;
		return -1;
	}	

	// print out the output header
	cout << "Binary\tDecimal" << endl;

	// loop through each line of the file
	while(!inFile.eof()) {
		string in_str;
		int pos = 0;
		unsigned int val = 0;  // I assume the values are all > 0
		bool isValid = true;
		
		// get a line 
		getline(inFile, in_str);
		
		// go past the leading spaces if any
		for(pos; pos < in_str.length(); pos++)
			if(in_str[pos] != ' ')
				break;
	
		// loop through each character in the line now
		for(pos; pos < in_str.length(); pos++) {

			// make sure the value is a one or zero, if neither set the valid flag
			// to false and break out of the loop
			if(in_str[pos] != '0' && in_str[pos] != '1') {
				isValid = false;
				break;
			}

			// use a binary shift operator to move the bits one to the left
			val = val << 1;
			if (in_str[pos] == '1')  // if the value is a one, add a bit to the rightmost part
				val = val | 1;		 // of the integer
				
		}
		
		// if we are at the end of the file, don't print
		if (!inFile.eof())
			if(isValid) // remember the valid flag? use it here to print out the proper message
				cout << in_str << '\t' << val << endl;
			else
				cout << in_str << "\tis not a valid binary number" << endl;
	}

	// make sure to clean up after ourselves
	inFile.close();


	return 0;
}

Reply With Quote
  #6  
Old July 13th, 2003, 06:16 AM
holguie81 holguie81 is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Jul 2003
Posts: 4 holguie81 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Quote:
Originally posted by Scorpions4ever
Bet you're using a mouldy old compiler like Borland C++ 3.0 or 4.0. The problem is, I used a loop variable 'i' a few lines above:
// First eliminate the leading spaces before the line
for (int i = 0; i < s.size(); i++, n_count++)

and then I used it again here:
for (int i = n_count; i < s.size(); i++)

The C++ standard says that this is perfectly valid, since 'i' will only have scope inside the loop. However, older C++ compilers didn't always do this. Instead, the first time you declared the variable, they would keep the scope for the rest of the function, instead of within the loop block alone. Hence, the compiler is complaining that 'i' was already declared. Go ahead and change the second loop variable to something else like 'j' and it should work fine.


I am using Microsoft Visual C++ 6.0

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Binary to Decimal


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway
Stay green...Green IT