#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    4
    Rep 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;
    }
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4247
    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? :D
    Last edited by Scorpions4ever; July 12th, 2003 at 11:13 AM.
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    4
    Rep 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! :)
  6. #4
  7. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,643
    Rep Power
    4247
    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.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    NY
    Posts
    18
    Rep 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;
    }
  10. #6
  11. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Posts
    4
    Rep Power
    0
    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

IMN logo majestic logo threadwatch logo seochat tools logo