Mushymon

Right now I have two completed projects, and the first one works perfectly, but is there a way to justify why a string with value 0 converted to an array becomes 48? First project is called "Binary to Decimal" and I have to create a documentation on it, but i have no clue how to answer the question of 0 becoming 48. The project is basically create a program that converts binary base two to a positive integer value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <string>
#include <iostream>
using namespace std;

int main(){
	string binary;
	cout << "Welcome to the \"Binary --> Decimal\" program." << endl;
	cout << "This program runs on a binary base two system." << endl;
	cout << "Please only use a maximum of 12 digits and only enter \"0\" and \"1\" only." << endl;
	cout << "Enter in \"00\" to shut down the program permanently." << endl;
	while(true){
		int total = 0, counter, code[12];
		float adder = 0.5;
		cout << "Please enter your binary number: ";
		cin >> binary;
		for(counter = 0; counter < 12; counter++){
			code[counter] = binary[counter];
		}
		for(counter = binary.size(); counter > -1; counter--){
			if(code[counter] == 49){
				total += adder;
			}
			adder *= 2;
		}
		if((code[0] == 48) && (code[1] == 48)){
			cout << "Thank you for using this program." << endl;
			break;
		}
		else{
			cout << "The decimal representation of the binary number is: ";
			cout << total << "." << endl << endl;
		}
	}
	return 0;
}
Last edited on
Sounds like it has something to do with the ASCII code for character '0' having the decimal value of 48.
http://www.asciitable.com/

I would tend to favour if (code[0] == '0')
rather than if (code[0] == 48)
Last edited on
Thank you Chervil for solving my problem. It was ASCII code all along since number 48 was just the symbol for zero. I still have another big issue with my second project though. This program seems to crash when I enter in something like "I'm not an idiot". The problem is somehow related to basic string::erase, but I don't know how to fix it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <string>
#include <iostream>
using namespace std;

int main() {
	cout << "Welcome to \"Idiot Strings\" program." << endl;
	cout << "This program detects any \"idiot\" in your sentences." << endl;
	cout << "Go ahead and try it, enter a random sentence." << endl;
	string idiot;
	while(true){
		getline(cin, idiot);
		unsigned find1,find2, find3, find4, find5;
		find1 = idiot.find_first_of("Ii");
		if(find1 == string::npos){
			cout << "No idiot in this sentence." << endl;
		}
		else{
			idiot.erase(0, find1);
			find2 = idiot.find_first_of("Dd");
			if(find2 == string::npos){
				cout << "No idiot in this sentence." << endl;
			}
			else{
				idiot.erase(find1, find2);
				find3 = idiot.find_first_of("Ii");
				if(find3 == string::npos){
					cout << "No idiot in this sentence." << endl;
				}
				else{
					idiot.erase(find2, find3);
					find4 = idiot.find_first_of("Oo");
					if(find4 == string::npos){
						cout << "No idiot in this sentence." << endl;
					}
					else{
						idiot.erase(find3, find4);
						find5 = idiot.find_first_of("Tt");
						if(find5 == string::npos){
							cout << "No idiot in this sentence." << endl;
						}
						else{
							cout << "We found an idiot!" << endl;
						}
					}
				}
			}
		}
		if((find1 == find2 -1) && (find2 == find3) && (find3 == find4) && (find4 == find5)){
			cout << "That was obvious" << endl;
		}
	}
	return 0;
}
I do not understand why you are erasing the string nevertheless what does this statements mean?

idiot.erase(find1, find2);
Last edited on
Sorry, I tried to debug your code, but I couldn't figure out a way to keep the original coding. This is the functional version I came up with, it has a nested while loop that turns every letter in the string to lower-case then checks for the full word "idiot", it will now detect "Idiot" "idiot's" "IdIoT", etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <string>
#include <iostream>
using namespace std;

int main() {
	cout << "Welcome to \"Idiot Strings\" program." << endl;
	cout << "This program detects any \"idiot\" in your sentences." << endl;
	cout << "Go ahead and try it, enter a random sentence." << endl;
	string idiot;
	while(true){
		getline(cin, idiot);

		int find1=0, count = 0, length = idiot.length();
		while(count<= length)//iterate through each letter in sentence, convert to lowercased
		{
			if(idiot[count] <= 'Z' && idiot[count] >= 'A')
			{
				idiot[count] = idiot[count] - 'A'+'a';
			}
			
			count++;
		}
		cout<<idiot;
		
		find1 = idiot.find("idiot");
		cout<<endl<<find1<<endl;
		if(find1 >= 0)
		{
			cout<<endl<<"We found the idiot"<<endl;
		}

		if(find1 < 5)//if idiot is started within 5 letters of the start
		{
			cout << "That was obvious" << endl;
		}
	}
	return 0;
}
Last edited on
@newbieg

When you declare your unsigned find variables, set each to zero, otherwise they are initialized with random garbage numbers.


This is totally unimportant for the code because they are assigned when they are used.
I actually edited that post right after making it, but I stand by what I said in it, the final if() in the code is testing for the values of find2 through find5 without assigning them a value, so they should be initialized to 0.
That doesn't solve the main problem, but assigning the value 0 in the beginning will at least get that final if() to run.
Last edited on
You are saying about the statement

1
2
		if((find1 == find2 -1) && (find2 == find3) && (find3 == find4) && (find4 == find5)){
			cout << "That was obvious" << endl;
}


But as I said early there is no any need in this set of variables and there is no any need to erase the string. It is enough to advance previously found position and start searching from this position.
Last edited on
Mushymon, this is the closest I could get to your original code, Like Vlad says, you don't need the string.erase() method. I think that it somehow ends up trying to access a member of the array that is beyond the length of the array, but I didn't find exactly where or how.

@ Vlad, try this without the unsigned vars being initialized with a value and try typing in a short word, 5 letters or less.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <string>
#include <iostream>
using namespace std;

int main() {
	cout << "Welcome to \"Idiot Strings\" program." << endl;
	cout << "This program detects any \"idiot\" in your sentences." << endl;
	cout << "Go ahead and try it, enter a random sentence." << endl;
	string idiot;
	while(true){
		getline(cin, idiot)
		unsigned find1=-1,find2=0, find3=0, find4=0, find5=0;
		int found = 0;
		while(found == 0)
		{
			find1 = idiot.find_first_of("Ii", find1+1);
			if(find1 == string::npos){
				found = 3; // no more I's left
			}
			else{
			find2 = idiot.find_first_of("Dd", find1);
			if(find2 == string::npos){
			}
			else{
				find3 = idiot.find_first_of("Ii", find2);
				if(find3 == string::npos){
				}
				else{
				find4 = idiot.find_first_of("Oo", find3);
					if(find4 == string::npos){
					}
					else{
						find5 = idiot.find_first_of("Tt", find4);
						if(find5 == string::npos){
							}
							else{
								cout << "We found an idiot!" << endl;
								found = 1;
							}
						}
					}
				}
			}
			if(found == 3)
			{
				cout<<"No idiots were found. ";
			}
			if((find1 == find2 -1) && (find2 == find3) && (find3 == find4) && (find4 == find5)){
				cout << "That was obvious" << endl;
			}
		}
	}
	return 0;
}
Last edited on
@newbieg
@ Vlad, try this without the unsigned vars being initialized with a value and try typing in a short word, 5 letters or less.


I am sorry but I have no any desire to spend much time in this thread. It is the second thread that is devoted to this question. The task is being done very simply by means of standard algorithm std::all_of and I wrote the corresponding code for myself when the first thread was discussed.:)
But even without the algorithm it is simply being done if to use another form of class string member function find (or find_first_of) with the second parameter that specifies starting position:)

The code could look for example like something as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>
#include <cctype>
 
int main()
{
    while ( true )
    {
        std::cout << "Enter a sentence (<enter> to quit): ";
        //      "i don't like to eat"
 
        std::string s;
        std::getline( std::cin, s );
 
        if ( s.empty() ) break;
 
        const std::string idiot = "idiot";
        
        std::string::size_type pos = 0;
        for ( char c : idiot )
        {
            char letter[] = { c, static_cast<char>( toupper( c ) ) };
            
            pos = s.find_first_of( letter, pos );
 
            if ( pos == std::string::npos ) break;
            
            ++pos;
        }
        
        if ( pos != std::string::npos )
        {
            std::cout << "There is word " << idiot 
                      << " in the entered sentence"
                      << std::endl;
        }
    }
}


But as I said I did the program for myself in another way.
Of course it would be better to write

const char letter[] = { c, static_cast<char>( toupper( c ) ) };

in the code I showed.
In fact the same way the program can be written in C#.
Thank you so much Newbieg, I learned a lot about the find function in strings after looking at your improved code. I did not know that you could just make string.find_first_of() continue where something else left off, so that is why I was using to prevent it from repeating itself. Thank you for your consideration too Vlad.
Your welcome
Here is the C# equivalent program for the C++ code above shown by me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System;

namespace Idiot
{
    /// <summary>
    /// Program Idiot. Copyright 2013, Vladimir Grigoriev (Vlad from Moscow)
    /// ====================================================================
    /// Determines whether a given word can be present in a sentence
    /// </summary>

    class Program
    {
        static void Run()
        {
            while (true)
            {
                Console.Write("Enter a sentence (<enter> to quit): ");
                //      "i don't like to eat"

                string s = Console.ReadLine();

                if (s.Trim().Length == 0) break;

                const string idiot = "idiot";

                int pos = 0;
                foreach (char c in idiot)
                {
                    char[] letter = { c, char.ToUpper(c) };

                    pos = s.IndexOfAny( letter, pos);

                    if (pos == -1) break;

                    ++pos;
                }

                Console.WriteLine("There is {0}word \"{1}\" in the sentence\n",
                                   pos == -1 ? "no " : "", idiot);
            }
        }

        static void Main()
        {
            Program.Run();
        }
    }
}
Last edited on
Topic archived. No new replies allowed.