Getting weird values of a variable while using recursion - c++

I wrote a program to print the sum of first 25 natural numbers using a recursive function.
It went fine and I also got the correct output(ie 325).
After that I played a little with my code just to see what happens.
Here is the code :
int su(int sum,int i)
{
if(i<26)
{
sum=sum+i+su(sum,i+1);
cout << sum << endl; // I added this line to see what happens.
// This line wasn't needed but I still
// added it.
}
else
return sum;
}
When I ran this code, it printed weird values of the variable sum.
Here is a screenshot the output : output
The sum of first 25 natural numbers is 325 but that doesn't even show up anywhere in the output. Instead, I got different numbers as in my output.
However when I remove the line cout << sum << endl; from the if statement, I get the expected sum (ie 325).
What is the cause of that?

Your non-void function does not return anything when i is less than 26 and this is undefined behavior. If you checked/turned on the compiler warnings you would see the warning:
warning: control reaches end of non-void function [-Wreturn-type]
}
^
Removing the already pointless else fixes that issue:
#include <iostream>
using namespace std;
int su(int sum,int i)
{
if(i<26)
{
sum=sum+i+su(sum,i+1);
cout<<sum<<endl;
}
// Removed the else. Always returns something
return sum;
}
int main() {
std::cout << su(0, 0) <<std::endl;
}
Output:
25
49
72
94
115
135
154
172
189
205
220
234
247
259
270
280
289
297
304
310
315
319
322
324
325
325
325
Always firstly make sure your recursive function eventually gets out of the loop and returns a value in case it's not void. A much simpler and cleaner way would be like this (a bit like the classic factorial function):
#include <iostream>
int sum (int i) {
if(i == 1) {
return 1;
}
return i + sum(i-1);
}
int main() {
std::cout << sum(25) <<std::endl;
}
Output:
325
If you add std::cout to see what's going on under the hood:
#include <iostream>
int sum (int i) {
std::cout << i << std::endl; // current integer
if(i == 1) {
return 1;
}
return i + sum(i-1);
}
int main() {
std::cout << sum(25) <<std::endl;
}
The output is as expected:
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
325

Your function doesn't return anything if not at the end of the recursion. Remove the else keyword it should work.

Related

How to find the count number of entries in map iterator in C++

I am new in C++.I am using STL Containers.I am mapping the AnimalWeightCAT to unique values of distance travel in km.Using this code
#include <iostream>
#include <map>
#include <sstream>
int main() {
std::istringstream file(
"3 138 3 239 3 440 3 241 3 462 3 432 3 404 2 435 2 514 2 565 3 328 3 "
"138 5 401 5 142 5 404 5 460 5 472 2 418 5 510 2");
// some typedefs to make it simpler:
typedef int AnimalWeightCAT_t;
typedef int distance_t;
typedef int count_t;
typedef std::map<distance_t, count_t> distcount_t;
typedef std::map<AnimalWeightCAT_t, distcount_t> AWeightDistance;
AWeightDistance AWeightDistanceCount; // map AnimalWeightCAT -> distances with counts
AnimalWeightCAT_t AnimalWeightCAT; // temporary variable to read a AnimalWeightCAT
distance_t dist; // temporary variable to read a distance
// read AnimalWeightCAT and distance until the file is depleated and use AnimalWeightCAT and dist as
// keys in the outer and inner map and increase the count:
while (file >> AnimalWeightCAT >> dist) ++AWeightDistanceCount[AnimalWeightCAT][dist];
for(AWeightDistance::iterator adit= AWeightDistanceCount.begin(); adit!= AWeightDistanceCount.end(); ++adit) {
std::cout << "AnimalWeightCAT: " << adit->first << '\n';
for(distcount_t::iterator dcit = adit->second.begin();dcit != adit->second.end();++dcit){
std::cout << '\t' << dcit->first << ' ' << dcit->second << '\n';
}
}
}
How i can find the count of number of distict in indices of AnimalWeightCAT of iterator aditby using map in C++?
Above code display the following output
Output:
AnimalWeightCAT: 2
418 1
435 1
514 1
565 1
AnimalWeightCAT: 3
138 2
239 1
241 1
328 1
404 1
432 1
440 1
462 1
AnimalWeightCAT: 5
142 1
401 1
404 1
460 1
472 1
510 1
I want this kind of output.How?
AnimalWeightCAT: 2 count = 4
AnimalWeightCAT: 3 count = 8
AnimalWeightCAT: 5 count = 6
For count of the second map adit->second.size() will be sufficient so your last loop, in order to look like you desire must be:
for(AWeightDistance::iterator adit = AWeightDistanceCount.begin();
adit != AWeightDistanceCount.end(); ++adit)
{
std::cout << "AnimalWeightCAT: " << adit->first
<< " count: " << adit->second.size() << '\n';
}
or simpler, using a range based for-loop:
for(auto&&[awc, dist_count] : AWeightDistanceCount) {
std::cout << "AnimalWeightCAT: " << awc
<< " count: "<< dist_count.size() << '\n';
}

data is not synchronized when try to implement a producer, consumer, ring buffer model

Correct Code Link: https://wandbox.org/permlink/JYr2XoaSxsS1QT14
I've been stuck for days because of this.. I tried to make a producer->ring buffer->consumer model. At first I used a mutex to make it, it works but it's not asynchronous. I want the consumer keeps reading without any stops, just like a video player, which I think I can't accomplish with a mutex.
Here's what I've done:
I make a FIFO structure based on fixed size dynamic array. (ring buffer)
I have a pair of pointers for both push_right and pop_left operations. So there won't have data race problems, if I understand correctly.
I make the producer to write several items ahead, then consumer starts to read and need to ensure that:
consumer reads speed <= producer writes speed (consumer read pointer < producer write pointer )
A appropriate fixed array size, so that the producer won't override items that consumer haven't read.
My problem is that the output result is not as I expected, it's not synchronized.. And I have no idea how to debug this.
You can see the data write order (P ostream:) is not the same as the read order (O ostream:).
One possible output:
data size: 20
70 927 156 109 834 26 883 576 226 500 904 777 935 80 346 559 846 879 548 791
********************
Consumer start working
791
548
879
846
26
346
109
156
927
70
500
226
576
883
26
834
109
156
927
70
Consumer done
********************
p_count: 20
c_count: 20
P ostream: 791 548 879 846 559 346 80 935 777 904 500 226 576 883 26 834 109 156 927 70
C ostream: 791 548 879 846 26 346 109 156 927 70 500 226 576 883 26 834 109 156 927 70
Code:
(It contains main.cpp, circular_array and a data txt file, so I
think visit the link would be less pain)
https://wandbox.org/permlink/ddQjNFdxABrjminQ
main.cpp
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
#include <fstream>
#include <sstream>
#include "circular_array.h"
using namespace ythlearn;
using namespace std;
int p_count = 0;
int c_count = 0;
int fileSize = 0;
ostringstream p_os, c_os;
void producer(CircularArray<int>* Ca, vector<int> &data){
for(int i = 0; i < 5; i++){
p_os << data.back() << " ";
Ca->push_right(data.back());
data.pop_back();
p_count++;
}
while(!data.empty()){
this_thread::sleep_for(chrono::seconds(1));
p_os << data.back() << " ";
Ca->push_right(data.back());
data.pop_back();
p_count++;
}
}
void consumer(CircularArray<int>* Ca){
cout << "********************" << endl;
cout << "Consumer start working" << endl;
this_thread::sleep_for(chrono::seconds(5));
while(c_count < fileSize){
this_thread::sleep_for(chrono::seconds(1));
int re = Ca->pop_left();
cout << re << endl;
c_os << re << " ";
c_count++;
}
cout << "Consumer done" << endl;
cout << "********************" << endl;
}
void getInput(vector<int>& data){
ifstream ifs("test.txt");
int j;
while(ifs >> j){
data.push_back(j);
}
}
int main(){
cout << unitbuf;
vector<int> data;
getInput(data);
CircularArray<int> Ca;
::fileSize = data.size();
cout << "data size: " << ::fileSize << endl;
for(const auto& s: data){
cout << s << " ";
}
cout << endl;
thread th_producer(producer, &Ca, std::ref(data));
thread th_consumer(consumer, &Ca);
th_consumer.join();
th_producer.join();
cout << "p_count: " << p_count << endl
<< "c_count: " << c_count << endl;
cout << "P ostream: " << p_os.str() << endl;
cout << "C ostream: " << c_os.str() << endl;
return 0;
}
circular_array.h
#pragma once
#include <stdexcept>
#include <iostream>
namespace ythlearn{
template<typename T>
class CircularArray{
public:
CircularArray(int N = 10){
head = tail = new T[N];
past_end_ptr1 = past_end_ptr2 = head + N;
start_ptr1 = start_ptr2 = head;
_capacity = N;
_size = 0;
}
void push_right(T elem){
*tail = elem;
if(tail + 1 == past_end_ptr1){
tail = start_ptr1;
}else{
tail++;
}
}
T pop_left(){
T re = *head;
if(head + 1 == past_end_ptr2){
head = start_ptr2;
}else{
head++;
}
return re;
}
CircularArray& operator=(const CircularArray&) = delete;
CircularArray(const CircularArray&) = delete;
~CircularArray(){
delete[] start_ptr1;
}
private:
T* head;
T* tail;
T* start_ptr1, *start_ptr2;
T* past_end_ptr1, *past_end_ptr2;
int _capacity;
int _size;
};
}
test.txt
70
927
156
109
834
26
883
576
226
500
904
777
935
80
346
559
846
879
548
791
Short version: The problem comes down to no implementation of the third thing you said you had done ("consumer read pointer < producer write pointer" and "the producer won't override items that consumer haven't read"). In particular, not checking for overwrite is being problematic. So good plan, not so good execution.
More details: You never check for the circular array being full. Since your test case lives on the border between the array being full and the array being overfull, you end up with a race condition. Sometimes the producer will overwrite the beginning of the array before the consumer reads it.
Here's a timeline (measured in seconds):
0: Producer writes 5 values to the array.
1: Producer writes a 6th value to the array.
2: Producer writes a 7th value to the array.
3: Producer writes an 8th value to the array.
4: Producer writes a 9th value to the array.
5: Producer writes a 10th value to the array (it's now at capacity), and Consumer starts its loop (but does not get far since the first step in each iteration is sleeping for a second).
5+n: Producer writes a value to the array, and Consumer reads a value from the array. If Producer goes first, the array's size temporarily goes up to 11, exceeding its capacity.
Look at the places where Consumer reads something different than what Producer wrote. Compare what Consumer read to what Producer wrote 10 steps later.
Now for the unasked-for general critique.
There are two aspects of your implementation of a circular array that look odd/wrong. First, there is the storage duplication, where you maintain two identical start pointers and two identical past-end pointers. Second, it looks like _size is always 0, which seems not helpful.
One aspect that is not necessarily wrong but that might be improvable is how you specify N. Have you considered making N a template parameter, similar to what was done for std::array? That could reduce your memory footprint (no need to store _capacity) and remove the need for dynamic memory management.
Addendum:
It has occurred to me that you have data members that should not be changed after construction, but that are not flagged const. You might want to address that, especially since flagging them const will make it clear that they cannot be involved in a race condition. So you could declare the circular array's data members more like:
private:
int const _capacity;
T * const start;
T * const past_end;
T* head;
T* tail;
Then the constructor could be more like:
CircularArray(int N = 10) :
_capacity(N),
start(new T[N]),
past_end(start + N)
{
head = tail = start;
}
(Actually, you could use the initializer list for all the members; I just thought smaller changes would be more digestible.) Another style benefit of this is that the new and delete would both be applied to start, which looks better to someone checking the code.
Another simplification might be to use the expression start + N wherever you had been using past_end. The performance difference should be negligible, and you reduce the memory footprint.
Alternatively, my earlier suggestion of making N a template parameter would render the const question moot. Using N as a template parameter (still with a default value of 10), the circular array's data members could simply be:
private:
T start[N]; // As a template parameter, N is a compile-time constant
T* head; // Or an index into the array
T* tail; // Or an index into the array
Switching to indices also gives more reason to drop the past-the-end member. The past-the-end index becomes N, which is a compile time constant -- no need to waste storage space on it.

How to find reverse relations between jobs?

I've been trying to find reverse relations between jobs. To be more specific I will tell it with an example.
Suppose I have n jobs i.e {0,1,2,3,4,...n}. I also have relations between jobs. I know only successor jobs, i.e., 2 is followed by 4,5. 5 is followed by 7,8 etc. I have it in a text file. I want to obtaing precedence relations between jobs (what is the predecessor job of 5?).
Having text output would be great. I have some code but it does not work.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
#define TOTAL_ACTIVITY 123
void readFile();
void change ();
void writeFile ();
struct Activity {
int precedessor [3];
int successor [3];
int id;
};
Activity activityList[TOTAL_ACTIVITY];
void main() {
readFile();
change();
writeFile();
}
void readFile() {
ifstream myReadFile;
myReadFile.open("pre.txt");
if (!myReadFile) { //check whether the file can be opened
cerr << "Unable to open file"; // terminate with error
}
while (!myReadFile.eof()) {
int Id,suc1, suc2, suc3;
int t = 0;
while (myReadFile >> Id >> suc1 >> suc2 >> suc3) //data should be in this order
{
activityList[t].id = Id;
activityList[t].successor [0] = suc1;
activityList[t].successor [1] = suc2;
activityList[t].successor [2] = suc3;
t++;
}
}
return;
}
void change() {
int act;
for (int i=1;i<TOTAL_ACTIVITY;i++){
for (int j=0;j<TOTAL_ACTIVITY;j++){
for (int k=0;k<3;k++) {
if (activityList[j].successor[k]==i;)
}
}
}
}
void writeFile() {
ofstream out("out.txt");
out << "id\t" << "Pre1\t" << "Pre2\t" << "Pre3\t"<<"\n";
for (int j = 0; j < TOTAL_ACTIVITY; j++) {
out << activityList[j].id << "\t";
out << activityList[j].precedessor[0]<< "\t";
out << activityList[j].precedessor[1] << "\t";
out << activityList[j].precedessor[2] << "\t";
out << "\n";
}
out.close();
}
Here is a sample input:
ID Successor1 Successor2 Successor3
1 2 3 4
2 6 11 15
3 7 8 13
4 5 9 10
5 20
6 30
7 27
8 12 19 27
9 14
10 16 25
11 20 26
12 14
13 17 18
14 17
15 25
16 21 22
17 22
18 20 22
19 24 29
20 23 25
21 28
22 23
23 24
24 30
25 30
26 31
27 28
28 31
29 32
30 32
31 32
Output should be something like this:
Id Predecesor1 Predecesor2 Predecesor3
........................................
...........................................
...........................................
You are given the successors of a job, but you do not need to retain this information.
For example, if I say: 5 -> 6, 7 meaning that 5 is followed by 6 and 7, then it is equivalent to saying that 6 and 7 are preceded by 5, right.
You can then either:
directly output the precedence when reading the successors
store in an associative container, using the job id as the key and the predecessor as value
Specifics details... are for you to work out to conclude your homework.

segmentation fault on getline in Ubuntu

I'm having the famous segmentation fault. I've tracked it down to a single line in the code (getline). Here's someone with a similar issue, also on Ubuntu:
http://www.daniweb.com/software-development/cpp/threads/329191
Note that getline returns -1 after the segmentation fault, but it couldn't have been really the end of the stream (in my case).
When the stream is smaller, everything goes ok. As we can deduce from the output, the segmentation fault is on line 98.
1 /*
2 * File: RequestDispatcher.cpp
3 * Author: albert
4 *
5 * Created on July 8, 2011, 7:15 PM
6 */
7
8 #include "iostream"
9 #include "fstream"
10 #include "stdlib.h"
11 #include "stdio.h"
12 #include "cstring"
13 #include "algorithm"
14
15 #include "RequestDispatcher.h"
16 #include "Functions.h"
17
18 #define PROXIES 1
19
20 RequestDispatcher::RequestDispatcher()
21 {
22 }
23
24 RequestDispatcher::RequestDispatcher(const RequestDispatcher& orig)
25 {
26 }
27
28 RequestDispatcher::~RequestDispatcher()
29 {
30 }
31
32 int RequestDispatcher::addRequest(string host, string request, IResponseReceiver* response_receiver)
33 {
34 RequestInfo info;
35 info.request_index = request_info.size();
36 info.host = host;
37 info.request = request;
38 info.response_receiver = response_receiver;
39 request_info.push_back(info);
40 return info.request_index;
41 }
42
43 void RequestDispatcher::run()
44 {
45 if (request_info.size()==0)
46 {
47 return;
48 }
49 FILE* pipe[PROXIES];
50 int per_proxy = (request_info.size() + PROXIES - 1) / PROXIES;
51 int count_pipes = (request_info.size() + per_proxy - 1) / per_proxy;
52 for (int pipe_index=0; pipe_index<count_pipes; ++pipe_index)
53 {
54 int from = pipe_index * per_proxy;
55 int to = min(from + per_proxy, int(request_info.size()));
56 cout << "FROM: "<< from << "; TO: " << to;
57 const char* cmd = generateCmd(from, to);
58 pipe[pipe_index] = popen(cmd, "r");
59 if (!pipe[pipe_index])
60 {
61 cerr << "Error executing command in RequestDispatcher::run()";
62 }
63 }
64 string result[PROXIES];
65 bool finished[PROXIES];
66 for (int pipe_index=0; pipe_index<count_pipes; pipe_index++)
67 {
68 finished[pipe_index] = false;
69 }
70 int count_finished = 0;
71 char* buffer;
72 size_t buffer_length=1024;
73 buffer = (char *) malloc (buffer_length + 1);
74 while (count_finished < count_pipes)
75 {
76 cout << "D\n";
77 fflush(stdout);
78 for(int pipe_index=0; pipe_index<count_pipes; ++pipe_index)
79 {
80 cout << "E\n";
81 fflush(stdout);
82 if (finished[pipe_index])
83 {
84 continue;
85 }
86 cout << "Getline" << buffer_length << "\n";
87 ssize_t bytes_read = getline(&buffer, &buffer_length, pipe[pipe_index]);
88 cout << "Getline Done ("<<bytes_read<< "," << buffer_length << ")\n";
89 fflush(stdout);
90 while (bytes_read>0)
91 {
92 for (int i=0; i<bytes_read; i++)
93 {
94 result[pipe_index] += buffer[i];
95 }
96 cout << "P\n";
97 fflush(stdout);
98 bytes_read = getline(&buffer, &buffer_length, pipe[pipe_index]);
99 cout << "Bytes read ("<<bytes_read<<","<< buffer_length << ")\n";
100 fflush(stdout);
101
102 }
103 if (bytes_read == -1) // then finished this pipe
104 {
105 string* r = &result[pipe_index];
106 //cout << *r;
107 finished[pipe_index] = true;
108 ++count_finished;
109 cout << "HI\n";
110 fflush(stdout);
111 // delete trailing '\0' from result
112 pclose(pipe[pipe_index]);
113 result[pipe_index] = result[pipe_index].substr(0, result[pipe_index].length()-1);
114 int pos = r->find("RESPONSE_DATA");
115 int valuepos, endvaluepos;
116 int request_index, length;
117 string headers;
118 int headerslength;
119 string body;
120 int bodypos, bodylength;
121 while (pos!=r->npos)
122 {
123 valuepos = r->find("REQUEST_INDEX=", pos) + 14;
124 endvaluepos = r->find("\n", valuepos);
125 request_index = pipe_index * per_proxy + atoi(r->substr(valuepos, endvaluepos-valuepos).c_str());
126
127 cout << "REQUEST_INDEX " << request_index;
128
129 valuepos = r->find("LENGTH=", pos) + 7;
130 endvaluepos = r->find("\n", valuepos);
131 length = atoi(r->substr(valuepos, endvaluepos-valuepos).c_str());
132
133 pos = r->find("START", pos)+5;
134 bodypos = r->find("\r\n\r\n", pos)+4;
135 headerslength = bodypos-pos-4;
136 bodylength = length-headerslength-4;
137 headers = r->substr(pos, headerslength);
138 body = r->substr(bodypos, bodylength);
139 request_info[request_index].response_receiver->notifyResponse(headers, body, request_index);
140
141 pos=r->find("RESPONSE_DATA", pos+length);
142 }
143 }
144 }
145 }
146 cout << "\n?\n";
147 fflush(stdout);
148 free(buffer);
149 request_info.clear();
150 }
151
152 const char* RequestDispatcher::generateCmd(int first_request, int to_request)
153 {
154 string r("/home/albert/apachebench-standalone-read-only/ab -a");
155 for (int i=first_request; i<to_request; i++)
156 {
157 r.append(" '");
158 r.append(request_info.at(i).request);
159 r.append("'");
160 }
161 ofstream out("/home/albert/apachebench-standalone-read-only/debug");
162 if(! out)
163 {
164 cerr<<"Cannot open output file\n";
165 return "";
166 }
167 out << r.c_str();
168 out.close();
169 return "/home/albert/apachebench-standalone-read-only/debug";
170 /*int size = strlen("/home/albert/apachebench-standalone-read-only/ab -a");
171 for (int i=first_request; i<to_request; i++)
172 {
173 size += 2+strlen(request_info.at(i).request)+1;
174 cout << "len: " << strlen(request_info.at(i).request) << "\n";
175 cout << "total: " << size << "\n";
176 }
177 size += 1;
178 char* cmd = new char[size];
179 strcpy(cmd, "/home/albert/apachebench-standalone-read-only/ab -a");
180 for (int i=first_request; i<to_request; i++)
181 {
182 cout << "LEN: " << strlen(cmd) << "\n";
183 cout << "NEXT: " << strlen(request_info.at(i).request) << "\n";
184 fflush(stdout);
185 strcat(cmd, " '");
186 strcat(cmd, request_info.at(i).request);
187 strcat(cmd, "'");
188 }
189 cout << "LEN: " << strlen(cmd) << "\n";
190 fflush(stdout);
191 return cmd;*/
192 }
When I run /home/albert/apachebench-standalone-read-only/debug from the command line everything works perfectly fine. It returns binary data.
The end of the output is:
P
Bytes read (272,6828)
P
Bytes read (42,6828)
P
Bytes read (464,6828)
P
Bytes read (195,6828)
P
Bytes read (355,6828)
P
Bytes read (69,6828)
P
Bytes read (111,6828)
P
Segmentation fault
Bytes read (368,6828)
P
Bytes read (-1,6828)
HI
REQUEST_INDEX 46REQUEST_INDEX 48REQUEST_INDEX 44REQUEST_INDEX 0REQUEST_INDEX 45
?
Mind the "?" for exiting the loop. After this, the program is finished.
By the way, I always thought the program would terminate on a segmentation fault (edit: I did not do anything to catch it).
In reply to some answers: There seem to be different versions of getline and I seem to be using the one documented here:
http://www.kernel.org/doc/man-pages/online/pages/man3/getline.3.html
So after some thought the issue I believe is that your buffer is being written to as you're reading it. In some cases the buffer is not done being written to and you remove some of the data from it (which could mean that you may read an empty buffer because the write isn't done). This is because you are using popen and simply piping data from another process. What I would recommend is that for one you use the C++ standard for getline (although both are somewhat unsafe) and that you have some leeway for reading data from the pipe. Retry logic might be what you need as I can't think of a clean way to solve this. If anyone knows please post it, I'm posting this because this is what I believe to be the likely culprit of the problem.
Also if you're coding in C++ I highly recommend that you use the C++ libraries so that you're not constantly mixing or casting between types (such as string to char * and such, it just saves you some hassle) and that you use the safer versions of methods so you avoid errors such as buffer overflows.

Problem with std::string::find()

I'm in trouble using std::string::find(). I read strings from console through the following code:
50 while(command.find(exitString) != 0) {
51 std::cout << "$ ";
52 getline(std::cin, command);
53
54 doSwitch(command);
55 }
and then I "switch" on them, through the following function:
59 void Console::doSwitch(std::string command) {
60 if(command.find(helpString) == 0) {
61 help();
62 } else if(command.find(loadString) == 0) {
63 try {
64 doLoad(command);
65 } catch(std::string str) {
66 std::cout << str << std::endl;
67 }
68 } else if(command.find(dumpProcString) == 0) {
69 try {
70 doDumpProc(command);
71 } catch(std::string str) {
72 std::cout << str << std::endl;
73 }
74 } else if(command.find(dumpMemString) == 0) {
75 doDumpMem();
76 } else if(command.find(defmemString) == 0) {
77 try {
78 doDefmem(command);
79 } catch(std::string str) {
80 std::cout << str << std::endl;
81 } catch(char *str) {
82 std::cout << str << std::endl;
83 }
84 } else if(command.find(resetString) == 0) {
85 try {
86 doReset();
87 } catch(std::string str) {
88 std::cout << str << std::endl;
89 }
90 } else {
91 std::cout << "Comando inválido." << std::endl;
92 }
93 }
but sometimes it simply doesn't switch correctly. Any clues?
Thanks in advance,
EDIT:
I've done some tests and I detected it was falling on the last else-if statement, instead of falling on the last else.
Then I checked my code again and found that the root cause was that I forgot to initialize resetString.
Problem solved!
Thank you everyone.
You might be expecting that find returns zero when it found the string, kind of like the way strcmp works.
But that's not how find works. find returns the first index of the found string, which might be zero, or might be something else if the string you're looking for is prepended with spaces, other strings, etc.
If find doesn't find what you're looking for, it returns string::npos. So your if...else block should be checking to find if the strings were found or not found, not checking to see if they were at index zero. Like this:
if(command.find(helpString) != string::npos ) {
help();
} else if /// ... etc...
You are reading a line and then calling doSwitch() without checking if its exitString. In that case, when the input is exitString, else block at the end of doSwitch() function is executed, causing the program to print "Command Invalido" before exiting the loop.
Is this what you observed?
If its something else, please let us know for what input your code behaves incorrectly and what is the input and output.