Unable to split strings read from a file and convert to decimal value.

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 560 Views - Last Post: 31 March 2011 - 07:27 AM Rate Topic: -----

#1 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 09:57 AM

Good day everyone.
I am trying to convert a 16 bit input read from a file to 3 parts consisting of 4, 4 and 8 bits respectively.
eg. 1011010100111101 to 1011 0101 00111101
This parts are then supposed to be converted to a decimal value. I have to read the I have tried using substrings, atoi, stringstream and all the methods i can think of, but i still seem to be doing something wrong. Please note that i am only a beginner. My course is an introductory one and we have covered selection, iteration, functions, arrays, structures, strings and files.

My log file currently consists of 2 data
1011100110110111
1000001110010101

Please help.

//Program to demonstrate a wind speed proccesor
//reads data from a log file and processes it to show the day, direction and speed of the wind
//calculates the maximum, mimimum and average speed
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>

using namespace std;
int binarytoDecimal(string);


int main()
{
	string inpStr,day, direction, speed;
	int W_speed, W_direction, W_day;

	//declare input file stream object to read the data
	ifstream inStream;

	//open the file
	inStream.open("data.txt", ios::app);
	
    
	//check if the file opened successfully
	if (inStream.is_open())
	{
		while(! inStream.eof())
		{

		//read the data from the file
		getline(inStream,inpStr);
		day = inpStr.substr(0,4);
		int atoi( const string *d );
		W_day = binarytoDecimal(d);

		getline(inStream,inpStr);
		direction = inpStr.substr(5,8);
		int atoi( const string *direction );
		W_direction = binarytoDecimal(dir);

		
		getline(inStream,inpStr);
		speed= inpStr.substr(9,8);
		int atoi( const string *wind );
		W_speed = binarytoDecimal(wind);
		
	

		cout<< day<<" "<< endl;
		cout<< direction<<" " << endl;
		cout<< speed<<" " << endl;

		if(inStream.eof())
			exit(1);
		}
	}
	else //file open failed
	{
		cout << "File open error "<< endl;
	}
			return 0;
}
int binarytoDecimal(string inpStr)
{
	int i ,res= 0 ;
	double power = 0.0;
	int digit;
	
	for(i = inpStr.length() - 1; i >= 0; i--)
	{
		digit = inpStr[i] - '0';
		res += (digit*pow(2.0,power ));
		power ++;
	}

	return res;
}    


The output im getting is
0
54
21

Is This A Good Question/Topic? 0
  • +

Replies To: Unable to split strings read from a file and convert to decimal value.

#2 jimblumberg  Icon User is online

  • member icon

Reputation: 3048
  • View blog
  • Posts: 9,283
  • Joined: 25-December 09

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 10:21 AM

This line you are trying to call the atoi() function int atoi( const string *d ); but this is actually a function definition. Also atoi works with C-strings (null terminated character strings). See this link for atoi(). To use atoi with std::string you must use the c_str() member function mvar = atoi(mstring.c_str());.

Also you are trying to use variables that you have not defined. In this line W_day = binarytoDecimal(d); you have never defined the variable d.

These are the error/warning messages I received when I compiled your code.

Quote

main.cpp||In function ‘int main()’:|
main.cpp|37|error: ‘d’ was not declared in this scope|
main.cpp|41|warning: redundant redeclaration of ‘int atoi(const std::string*)’ in same scope|
main.cpp|36|warning: previous declaration of ‘int atoi(const std::string*)’|
main.cpp|42|error: ‘dir’ was not declared in this scope|
main.cpp|47|warning: redundant redeclaration of ‘int atoi(const std::string*)’ in same scope|
main.cpp|41|warning: previous declaration of ‘int atoi(const std::string*)’|
main.cpp|48|error: ‘wind’ was not declared in this scope|
main.cpp||In function ‘int binarytoDecimal(std::string)’:|
main.cpp|75|error: ‘pow’ was not declared in this scope|
||=== Build finished: 4 errors, 4 warnings ===|


To use the pow() function you must include the cmath header file.

You should also probably study these links Variables, Functions I and Functions II.

Jim
Was This Post Helpful? 1
  • +
  • -

#3 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 10:46 AM

okay, i overlooked declaring variables because i was changing the names. thanks. so, ive modified that section of my code to

          getline(inStream,inpStr);
		day = inpStr.substr(0,4);
		int ans1 = atoi(day.c_str());
		W_day = binarytoDecimal(day);

		getline(inStream,inpStr);
		direction = inpStr.substr(5,8);
		int ans2 = atoi(direction.c_str());
		W_direction = binarytoDecimal(direction);

		
		getline(inStream,inpStr);
		speed= inpStr.substr(9,8);
		int ans3 = atoi(speed.c_str());
		W_speed = binarytoDecimal(speed);
		
	

		cout<< W_day<<" "<< endl;
		cout<< W_direction<<" " << endl;
		cout<< W_speed<<" " << endl;



but im getting the same output.
Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg  Icon User is online

  • member icon

Reputation: 3048
  • View blog
  • Posts: 9,283
  • Joined: 25-December 09

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 11:18 AM

First getline() will get an entire line from the file so every time you call get line you will get a new string. You only need to call getline once.

Second the std::string.substr() the first parameter is the starting point the second parameter is the number of characters. Remember that in C++ the first letter in an array or string is at location 0 not 1. So you need to start a 0 and you want 4 characters (0,1,2,3) next you want the next character (4) and you want 4 characters 4,5,6,7 next you want the next character (8) and you want 8 characters (8,9,10,11,12,13,14,15).

Since you are not using the value returned by atoi() I have removed that call. The following code seems to work.

getline(inStream,inpStr); // Only call once per line
day = inpStr.substr(0,4);
W_day = binarytoDecimal(day);

direction = inpStr.substr(4,4); 
W_direction = binarytoDecimal(direction);

speed= inpStr.substr(8,8);
W_speed = binarytoDecimal(speed);

cout<< W_day<<" "<< endl;
cout<< W_direction<<" " << endl;
cout<< W_speed<<" " << endl;



Jim
Was This Post Helpful? 1
  • +
  • -

#5 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 11:36 AM

ok, but i have tried this method much earlier. i am just getting a runtime error. no output

R6010
-abort called
Was This Post Helpful? 0
  • +
  • -

#6 Bench  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 844
  • View blog
  • Posts: 2,334
  • Joined: 20-August 07

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 11:37 AM

C++ has got a tool called std::bitset which will do this job for you. a bitset is designed to read in binary text representations of data such as the string of 1's and 0's you've got there.

#include <iostream>
#include <fstream>
#include <bitset>

int main()
{
    std::ifstream input("C:\\myfile.txt");
    std::bitset<4> nibble1;
    std::bitset<4> nibble2;
    std::bitset<8> octet;
    if (input >> nibble1 >> nibble2 >> octet)
    {
        std::cout << nibble1 << " " 
                  << nibble2 << " " 
                  << octet << std::endl;
    }
} 



Also, you shouldn't use atoi in C++ code - not just because its an old 'C' function (Although that's reason enough to avoid it too), more importantly its an unreliable function because it returns a value of zero if it encounters an error; Which means that its impossible to tell whether a conversion is successful or not, on the basis that zero is a valid number. i.e. imagine your file had some dodgy data in it such as "hello world", 'atoi' will return the same value for a string of "hello world" as it would for a string of "0". - chances are that you wouldn't want "hello world" evaluating to a legit number.

However, there's a much better alternative in the C++ libary (within the <sstream> header); you should prefer stringstream to convert between strings and numbers, which can be checked using the >> operator in an if statement. i.e.
std::string fred("10");
std::istringstream buffer(fred);
int num;
if (buffer >> num)
{
    //TODO: use 'num' for something
} 
stringstreams have the advantage of being reliable, and able to cope with representations for all of the built-in types (including bool, double, etc).
Was This Post Helpful? 1
  • +
  • -

#7 jimblumberg  Icon User is online

  • member icon

Reputation: 3048
  • View blog
  • Posts: 9,283
  • Joined: 25-December 09

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 11:50 AM

Your runtime error may be caused if you use std::string.substr() and the first parameter is larger than the string. Before you start using the substr function you should check the length of the string

if(inpStr.length() < 9)
   // do somethine.


I did not check if you were reading your file correctly. But the use of eof() in your while loop suggests problems. See this link.


Jim
Was This Post Helpful? 1
  • +
  • -

#8 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 12:08 PM

thank u for ur help. using the bitset stream i am able to separate the code, but only the first one. and it is somehow an infinity loop.
Was This Post Helpful? 0
  • +
  • -

#9 JaKWaC  Icon User is offline

  • D.I.C Head

Reputation: 76
  • View blog
  • Posts: 232
  • Joined: 15-November 10

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 12:19 PM

Can you post your code so we know where you have inserted the bitset example? Its hard to debug an infinite loop when you dont have the code ;)

This post has been edited by JaKWaC: 30 March 2011 - 12:20 PM

Was This Post Helpful? 0
  • +
  • -

#10 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 07:53 PM

okay, i will do that as soon as possible. however, i would like to know if its possible to use my earlier code using getline and substrings as it directly converts the input read to a decimal. also, i would REALLY like to know where im going wrong with it as im still not obtaining the correct output after 3 days of attempts. i have checked with many others who are doing this code and they seem to be able to do it using the getline, substr and the binarytodecimal function.

is it posible that i have to store all this values in an array first before each conversion can take place properly?

i really appreciate all the given help.
Was This Post Helpful? 0
  • +
  • -

#11 JaKWaC  Icon User is offline

  • D.I.C Head

Reputation: 76
  • View blog
  • Posts: 232
  • Joined: 15-November 10

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 07:56 PM

Post your code so we know what your working with. You've probably changed it a bit.
Was This Post Helpful? 0
  • +
  • -

#12 jimblumberg  Icon User is online

  • member icon

Reputation: 3048
  • View blog
  • Posts: 9,283
  • Joined: 25-December 09

Re: Unable to split strings read from a file and convert to decimal value.

Posted 30 March 2011 - 08:05 PM

Along with posting the current code post a small sample of your input file.

Jim
Was This Post Helpful? 0
  • +
  • -

#13 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Re: Unable to split strings read from a file and convert to decimal value.

Posted 31 March 2011 - 02:17 AM

//Program to demonstrate a wind speed proccesor
//reads data from a log file and processes it to show the day, direction and speed of the wind
//calculates the maximum, mimimum and average speed
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
int binarytoDecimal(string);


int main()
{
	string inpStr,day, direction, speed;
	int W_speed, W_direction, W_day;

	//declare input file stream object to read the data
	ifstream inStream;

	//open the file
	inStream.open("data.txt", ios::app);
	
    
	//check if the file opened successfully
	if (inStream.is_open())
	{
		while(! inStream.eof())
		{

		//read the data from the file


		getline(inStream,inpStr);
		
		
		day = inpStr.substr(0,4);
		W_day = binarytoDecimal(day);
		
		direction = inpStr.substr(4,4);
		W_direction = binarytoDecimal(direction);
		
		speed= inpStr.substr(8,8);
		W_speed = binarytoDecimal(speed);
		
		cout<< W_day<<" "<< endl;
		cout<< W_direction<<" " << endl;
		cout<< W_speed<<" " << endl;




		if(inStream.eof())
			exit(1);
		}
	}
	else //file open failed
	{
		cout << "File open error "<< endl;
	}
			return 0;
}
int binarytoDecimal(string inpStr)
{
	int i ,res= 0 ;
	double power = 0.0;
	int digit;
	
	for(i = inpStr.length() - 1; i >= 0; i--)
	{
		digit = inpStr[i] - '0';
		res += (digit*pow(2.0,power ));
		power ++;
	}

	return res;
}




data. txt
1011100110110111
1000001110010101

This post has been edited by shumi91: 31 March 2011 - 02:19 AM

Was This Post Helpful? 0
  • +
  • -

#14 jimblumberg  Icon User is online

  • member icon

Reputation: 3048
  • View blog
  • Posts: 9,283
  • Joined: 25-December 09

Re: Unable to split strings read from a file and convert to decimal value.

Posted 31 March 2011 - 05:54 AM

One of the problems you are having is that you are using eof() in your while statement. The eof() will not evaluate to false until after you try to read past the end of file. See this link about using eof().
Another problem is that using std::string.substr() will throw an out_of_range exception when the first parameter is larger than the string.length().

To solve your problems use your getline() in your while loop since it will report a failure if it can not read any characters. And secondly check that the length of the string is long enough, if it is not then just skip the rest of the loop (continue;) and get the next line.

		while(getline(inStream,inpStr))
		{
         if(inpStr.length() < 9)
         {
            cout << "Error reading input string. Length = " << inpStr.length() << endl;
            continue;
         }



Jim
Was This Post Helpful? 1
  • +
  • -

#15 shumi91  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 30-March 11

Re: Unable to split strings read from a file and convert to decimal value.

Posted 31 March 2011 - 06:57 AM

thank you for that information. i think now i have learnt why books say that programmers prefer the 'while' method. ok, i have implemented ur ideas, and i also modified the code a little bit to increase efficiency. i am getting the correct output, however the error message "Error reading input string. Length = 0" is appearing once above the output and another 6 times below it. How do I solve this?
Here is my code.
    #include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
using namespace std;



int main()
{
	string inpStr,day, direction, speed;
	
	//declare input file stream object to read the data
	ifstream inStream;

	//open the file
	inStream.open("data.txt", ios::app);
	
    
	//check if the file opened successfully
	if (inStream.is_open())
	{

		//read the data from the file

		while (getline(inStream,inpStr))
		{

		if(inpStr.length() < 9)
		{
			cout << "Error reading input string. Length = " << inpStr.length() << endl;
			continue;
		}


		day = inpStr.substr(0,4);
		direction = inpStr.substr(4,4);
		speed= inpStr.substr(8,8);

		cout << strtol (day.c_str (), NULL, 2) << endl;
		cout << strtol (direction.c_str (), NULL, 2) << endl;
		cout << strtol (speed.c_str (), NULL, 2) << endl;
		
		}
	}
	else //file open failed
	{
		cout << "File open error "<< endl;
	}
			return 0;
}
  

This post has been edited by shumi91: 31 March 2011 - 07:02 AM

Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2