return from my function is nan

U

utab

Dear all,

I tried sth easy(actually this was an exercise) but I tried to use the
standard lib. heavily for this problem(as far as I can). There was one
point I could not figure out. The problem is :

../a.out 1.3+3.2+.1+40/3*8/7-4*5-32

The program will parse the argument and find the result of the above
expression. I have two versions(the 2nd is working , not perfect ;-}),
but the first have a return problem I guess because if I use that
version I get "nan" as the result at line 37. What is my problem?

Sorry that there are some comments and cout statement in around the
code. But I guess it could be easier to figure out.

My Best,

1: this version returns nan from the "performer function"
--------------
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <sstream>
7 #include <algorithm>
8 #include <cstdlib>
9 using namespace std;
10
11 template <typename T>
12 T str_To_num (const std::string & s)
13 {
14 T result;
15 std::istringstream stream (s);
16 if (stream >> result)
17 return result;
18 else{
19 cerr << "error in conversion" <<endl;
20 return EXIT_FAILURE;
21 }
22 }
23 void parse_string(const
string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_type index;
28 while((index=str_temp.find_first_of(operators))!
=string::npos){
29 operators_vec.push_back(str_temp[index]);
30 value=str_temp.substr(0,index);
31
string_num_vec.push_back(str_To_num<double>(value));
32 str_temp=str_temp.substr(index+1);
33
if(str_temp.find_first_of(operators)==string::npos)
34
string_num_vec.push_back(str_To_num<double>(str_temp));
35 }
36 }
37 double performer(vector<double>&vec_d,vector<char>&vec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),pm.begin(),pm.end())
)!=vec_ch.end())
46 ;
47 else
48 ;
49 switch (*iter){
50 case '*':
51 index = iter-vec_ch.begin();
52 result_temp=vec_d[index]*vec_d[index+1];
53
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
78 for(vector<double>::const_iterator
i=vec_d.begin();i!=vec_d.end();++i)
79 cout << *i << endl;
80 cout << "------------"<<endl;
81 performer(vec_d,vec_ch);
82 }
83 else
84 return vec_d[0];
85 }
86 int main(int argc, char *argv[]){
87 if(argc!=2){
88 cout << "Usage error should be: <program_name
<mathematical expression> >" << endl;
89 cout << "Example: operator 1.3+3.2+.
1+40/3*8/7-4*5-32" << endl;
90 return EXIT_FAILURE;
91 }
92 // convert c-style string argument to a c++ string
93 string arg(argv[1]);
94 //cout << arg << endl;
95 vector<double> nums;
96 vector<char> ops;
97 parse_string(arg,nums,ops);
98 cout << performer(nums,ops) << endl;
99 return 0;
100}

2: on this version, at the end vector includes only one element that
is the result
-------------------------

1 // C++ way of parsing: heavy use of standard library, string parsing
functions
2 //
=======================================================================
=====
3 #include <iostream>
4 #include <string>
5 #include <vector>
6 #include <sstream>
7 #include <algorithm>
8 #include <cstdlib>
9 using namespace std;
10
11 template <typename T>
12 T str_To_num (const std::string & s)
13 {
14 T result;
15 std::istringstream stream (s);
16 if (stream >> result)
17 return result;
18 else{
19 cerr << "error in conversion" <<endl;
20 return EXIT_FAILURE;
21 }
22 }
23 void parse_string(const
string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
24 string str_temp=str;
25 string operators("+-*/");
26 string value;
27 string::size_type index;
28 while((index=str_temp.find_first_of(operators))!
=string::npos){
29 operators_vec.push_back(str_temp[index]);
30 value=str_temp.substr(0,index);
31
string_num_vec.push_back(str_To_num<double>(value));
32 str_temp=str_temp.substr(index+1);
33
if(str_temp.find_first_of(operators)==string::npos)
34
string_num_vec.push_back(str_To_num<double>(str_temp));
35 }
36 }
37 void performer(vector<double>&vec_d,vector<char>&vec_ch){
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),pm.begin(),pm.end())
)!=vec_ch.end())
46 ;
47 else
48 ;
49 switch (*iter){
50 case '*':
51 index = iter-vec_ch.begin();
52 result_temp=vec_d[index]*vec_d[index+1];
53
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
78 performer(vec_d,vec_ch);
79 }
80 //else
81 // return vec_d[0];
82 }
83 int main(int argc, char *argv[]){
84 if(argc!=2){
85 cout << "Usage error should be: <program_name
<mathematical expression> >" << endl;
86 cout << "Example: operator 1.3+3.2+.
1+40/3*8/7-4*5-32" << endl;
87 return EXIT_FAILURE;
88 }
89 // convert c-style string argument to a c++ string
90 string arg(argv[1]);
91 //cout << arg << endl;
92 vector<double> nums;
93 vector<char> ops;
94 parse_string(arg,nums,ops);
95 //cout << performer(nums,ops) << endl;
96 performer(nums,ops);
97 for(vector<double>::const_iterator iter=nums.begin();iter!
=nums.end();++iter)
98 cout << *iter << endl;
99 //for(vector<char>::const_iterator iter=ops.begin();iter!
=ops.end();++iter)
100 // cout << *iter << endl;
101 return 0;
102 }
 
N

noone

Dear all,

I tried sth easy(actually this was an exercise) but I tried to use the
standard lib. heavily for this problem(as far as I can). There was one
point I could not figure out. The problem is :

./a.out 1.3+3.2+.1+40/3*8/7-4*5-32

The program will parse the argument and find the result of the above
expression. I have two versions(the 2nd is working , not perfect ;-}), but
the first have a return problem I guess because if I use that version I
get "nan" as the result at line 37. What is my problem?

Sorry that there are some comments and cout statement in around the code.
But I guess it could be easier to figure out.

ummm....

I was going to suggest that you read the "dragon book" but upon closer
examination consider this. Since you are calling a.out remember that UNIX
shells usually expand '*' characters to wildcards. Quote your expression
then see what happens.
 
O

Ondra Holub

37 double performer(vector said:
38 double result_temp;
39 string md("*/");
40 string pm("+-");
41 vector<char>::iterator iter;
42 vector<int>::size_type index;
43
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
)!=vec_ch.end())
44 ;
45 else
if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),pm.begin(),pm.end())
)!=vec_ch.end())
46 ;
47 else
48 ;
49 switch (*iter){
50 case '*':
51 index = iter-vec_ch.begin();
52 result_temp=vec_d[index]*vec_d[index+1];
53
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
54 vec_ch.erase(iter);
55 break;
56 case '/':
57 index = iter-vec_ch.begin();
58 result_temp=vec_d[index]/vec_d[index+1];
59
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
60 vec_ch.erase(iter);
61 break;
62 case '+':
63 index = iter-vec_ch.begin();
64 result_temp=vec_d[index]+vec_d[index+1];
65
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
66 vec_ch.erase(iter);
67 break;
68 case '-':
69 index = iter-vec_ch.begin();
70 result_temp=vec_d[index]-vec_d[index+1];
71
vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
+index)),result_temp);
72 vec_ch.erase(iter);
73 break;
74 default:
75 ;
76 }
77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
78 for(vector<double>::const_iterator
i=vec_d.begin();i!=vec_d.end();++i)
79 cout << *i << endl;
80 cout << "------------"<<endl;
81 performer(vec_d,vec_ch);

Here is undefined return value.
82 }
83 else
84 return vec_d[0];
85 }

You should try to compile it with all warnings turned on. Then you
will see, that in function perform is sometimes undefined returned
value, because it simply does not return any value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top