Counting letters in a string

Pages: 12
I would like to know how I should go about counting letters in a string. I want to count letters in a string so that I can do math with each letter count and display results of the math in windows. I've already done it in the console and now I want to upgrade to windows.
I am not sure what you mean but this is how I would do it:

1
2
3
4
5
int count = 0;
char ch;
while(cin.get(ch) != '.')
count++;
cout << "Numbers of characters read: " << count;


and from there you can make whatever you want, examples are, a program that countes spaces, a program that counts words and so on.
A Windows GUI app can use the same code to count the letters in a string as a console app (which you say you've already written). It's the display code that would have to be different.

Andy

PS The Win32 API does provide alternatives to the standard string processing functions, but normally you stick to the standard ones.

Cool, thanks. No wonder it compiled alright with the console code. I just needed to figure out how to link the input and output with the code.
If I have a string variable such as str and str[] already in my console code, how would I go about tying that to an input text box and having the output at least go to a read only text box for starters? I screwed up with that before and I wanna find out the right way to do it.
Are you using old-school windowing? (i.e. WinMain, WindowProc, RegisterClassEx, CreateWindowEx, SetWindowText, etc.)? Or some other way??

Andy
Last edited on
I use old school char arrays to do all my dirty work.

char *phrase = new char[64]; // now you have an array 64 chars long

I wrote a function that would check to see how many actual characters were in the array.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int SizeofCharArray(char *phrase)
{
    int size = 0;

     int value = phrase[size];

     while(value != 0)
     {
           value = phrase[size];
           size++;
           
      };

      //printf("%i%s", size, "\n");

  return size;
};


Makes things easier to find little shortcuts until a real answer is found.



I'm using a windows form in Microsoft Visual Studio 2010.
So you're using C++/CLI rather than C++ then?
I guess so. What I want to know is how I can equate this->textBox1-> with char str[4095] = ""; for the text input. I also want to output ten int variables to a read only text box called this->textBox2->
Setting the text of a text box is straightforward enough

this->textBox1->Text = L"Hello world";

But you can't use a char* for the value of text: it requires a System::String^. So you'll need to convert any char* values, etc you use. Or work with the System::String directly, rather than a char*

1
2
3
const char* msg= "Hello, world!";
String^ cli_msg = gcnew String(msg);
this->textBoxText->Text = cli_msg;


Note that the issue isn't Windows GUI vs console. It's because you're swapping to another language (C++/CLI vs C++) when you work with the .Net Form library.

Andy
Last edited on
Yes, this-> is what I figured that I needed to do. Hopefully I can get things working good. I'll let you know what happens. Would the output need to be converted to a system string too or is there a way to output int's into a text box?
Maybe I should show you my code so that you can know what I'm doing exactly:

Here is Form1.h
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#pragma once

namespace NTS {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::TextBox^  textBox1;
	private: System::Windows::Forms::Button^  button1;
	private: System::Windows::Forms::TextBox^  textBox2;

	protected: 

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->textBox1 = (gcnew System::Windows::Forms::TextBox());
			this->button1 = (gcnew System::Windows::Forms::Button());
			this->textBox2 = (gcnew System::Windows::Forms::TextBox());
			this->SuspendLayout();
			// 
			// textBox1
			// 
			this->textBox1->AcceptsReturn = true;
			this->textBox1->CharacterCasing = System::Windows::Forms::CharacterCasing::Upper;
			this->textBox1->Font = (gcnew System::Drawing::Font(L"Times New Roman", 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->textBox1->Location = System::Drawing::Point(13, 394);
			this->textBox1->Margin = System::Windows::Forms::Padding(4);
			this->textBox1->Name = L"textBox1";
			this->textBox1->Size = System::Drawing::Size(450, 26);
			this->textBox1->TabIndex = 0;
			this->textBox1->Text = L"TYPE NAME OR WORD";
			this->textBox1->TextChanged += gcnew System::EventHandler(this, &Form1::textBox1_TextChanged);
			// 
			// button1
			// 
			this->button1->Font = (gcnew System::Drawing::Font(L"Times New Roman", 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->button1->Location = System::Drawing::Point(471, 394);
			this->button1->Margin = System::Windows::Forms::Padding(4);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(118, 26);
			this->button1->TabIndex = 1;
			this->button1->Text = L"ENTER";
			this->button1->UseVisualStyleBackColor = true;
			// 
			// textBox2
			// 
			this->textBox2->BackColor = System::Drawing::SystemColors::Window;
			this->textBox2->Cursor = System::Windows::Forms::Cursors::Arrow;
			this->textBox2->Location = System::Drawing::Point(13, 24);
			this->textBox2->Multiline = true;
			this->textBox2->Name = L"textBox2";
			this->textBox2->ReadOnly = true;
			this->textBox2->Size = System::Drawing::Size(576, 354);
			this->textBox2->TabIndex = 2;
			this->textBox2->TextChanged += gcnew System::EventHandler(this, &Form1::textBox2_TextChanged);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(9, 19);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(600, 433);
			this->Controls->Add(this->textBox2);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->textBox1);
			this->Font = (gcnew System::Drawing::Font(L"Times New Roman", 12, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->Margin = System::Windows::Forms::Padding(4);
			this->Name = L"Form1";
			this->Text = L"NTS";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	private: System::Void textBox1_TextChanged(System::Object^  sender, System::EventArgs^  e) {
			 }
	private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
			 }
	private: System::Void dataGridView1_CellContentClick(System::Object^  sender, System::Windows::Forms::DataGridViewCellEventArgs^  e) {
			 }
private: System::Void textBox2_TextChanged(System::Object^  sender, System::EventArgs^  e) {
		 }
};
}
Here is NTS.cpp
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// NTS.cpp : main project file.

#include "stdafx.h"
#include "Form1.h"

#include <iostream>
#include <conio.h>
#include <algorithm>
#include <string>

using namespace NTS;

using namespace std;

      int acount;
      int bcount;
      int ccount;
      int dcount;
      int ecount;
      int fcount;
      int gcount;
      int hcount;
      int icount;
      int jcount;
      int kcount;
      int lcount;
      int mcount;
      int ncount;
      int ocount;
      int pcount;
      int qcount;
      int rcount;
      int scount;
      int tcount;
      int ucount;
      int vcount;
      int wcount;
      int xcount;
      int ycount;
      int zcount;
      
      int sphere1 = 1;   
      int sphere2 = 2;
      int sphere3 = 3;
      int sphere4 = 4;
      int sphere5 = 5;
      int sphere6 = 6;
      int sphere7 = 7;
      int sphere8 = 8;
      int sphere9 = 9;
      int sphere0 = 10;
      
      int count1;
      int count2;
      int count3;
      int count4;
      int count5;
      int count6;
      int count7;
      int count8;
      int count9;
      int count0;

      int rsphere1;      
      int rsphere2;
      int rsphere3;
      int rsphere4;
      int rsphere5;
      int rsphere6;
      int rsphere7;
      int rsphere8;
      int rsphere9;
      int rsphere0;
      
       int CountCharacter( char * str , char ch )
       {
       int countChar = 0;
       for ( int i = 0; str[i] != '\0'; i++)
       {
       if ( str[i] == ch )
       countChar = countChar + 1;
       }
       return countChar;
       }

[STAThreadAttribute]
int main(array<System::String ^> ^args)
{

	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	// Create the main window and run it
	Application::Run(gcnew Form1());

	char str[4095] = "";

	  acount = CountCharacter( str , 'A' );
      bcount = CountCharacter( str , 'B' );
      ccount = CountCharacter( str , 'C' );
      dcount = CountCharacter( str , 'D' );
      ecount = CountCharacter( str , 'E' );
      fcount = CountCharacter( str , 'F' );
      gcount = CountCharacter( str , 'G' );
      hcount = CountCharacter( str , 'H' );
      icount = CountCharacter( str , 'I' );
      jcount = CountCharacter( str , 'J' );
      kcount = CountCharacter( str , 'K' );
      lcount = CountCharacter( str , 'L' );
      mcount = CountCharacter( str , 'M' );
      ncount = CountCharacter( str , 'N' );
      ocount = CountCharacter( str , 'O' );
      pcount = CountCharacter( str , 'P' );
      qcount = CountCharacter( str , 'Q' );
      rcount = CountCharacter( str , 'R' );
      scount = CountCharacter( str , 'S' );
      tcount = CountCharacter( str , 'T' );
      ucount = CountCharacter( str , 'U' );
      vcount = CountCharacter( str , 'V' );
      wcount = CountCharacter( str , 'W' );
      xcount = CountCharacter( str , 'X' );
      ycount = CountCharacter( str , 'Y' );
      zcount = CountCharacter( str , 'Z' );
      _getche();
      
      count1 = acount + icount + jcount + kcount + qcount + tcount + ycount;
      count2 = bcount + kcount + lcount + rcount + ucount;
      count3 = ccount + gcount + lcount + mcount + scount + xcount;
      count4 = dcount + mcount + ncount + tcount + ycount;
      count5 = ecount + hcount + ncount + ocount + xcount;
      count6 = fcount + jcount + pcount + ucount + vcount + wcount;
      count7 = gcount + ocount + qcount + vcount + zcount;
      count8 = fcount + hcount + pcount + rcount;
      count9 = icount + scount;
      count0 = jcount + kcount + lcount + mcount + ncount + ocount + pcount + qcount + rcount + scount + tcount + ucount + vcount + wcount + xcount + ycount;
      
       rsphere1 = sphere1 * count1;
       rsphere2 = sphere2 * count2;
       rsphere3 = sphere3 * count3;
       rsphere4 = sphere4 * count4;
       rsphere5 = sphere5 * count6;
       rsphere6 = sphere6 * count6;
       rsphere7 = sphere7 * count7;
       rsphere8 = sphere8 * count8;
       rsphere9 = sphere9 * count9;
       rsphere0 = sphere0 * count0;

	return 0;
}
You really need to give it another go, as it's rather repetitive and verbose!

The ascii codes for 'A', 'B', 'C', ... are a series. So you know that 'A' - 'A' = 0, 'B' - 'A' = 1, 'C' - 'A' = 2, ...

Can you see how that allows you to work with an array?

Andy

PS Be sure to check that the char you're counting is a letter, rather than a number, punctuation mark, etc. before calculating the offset to 'A'. And don't forget case either!
I'm working on a numerology program where specific numbers are associated with each letter. The numerology math works a certain way where I have to count the numbers that all the letters cause, to do multiplication with each number type. This code works in the console, cause I tested it. Now I want to do input and output with it in windows.
Well, if you want to use your existing C++ code with a C++/CLI GUI then you'll need to convert the System::Strings back and forth between char*

As I showed above, char* to System::String is easy enough: you just construct a System::String from the char*

1
2
3
const char* msg= "Hello, world!";
String^ cli_msg = gcnew String(msg);
this->textBoxText->Text = cli_msg;


The reverse, System::String to char*, is a bit more involved:

1
2
3
4
5
char buffer[1024]; // need to be careful with buffer size in real code
IntPtr hglob = Marshal::StringToHGlobalAnsi(cli_msg);
char* msg = static_cast<char*>(hglob.ToPointer());
strcpy(buffer, msg);
Marshal::FreeHGlobal(hglob);


where you can read the TextBox like:

String^ input = this->textBoxInput->Text;

Andy

PS For more info, see

How to convert from System::String* to Char* in Visual C++
http://support.microsoft.com/kb/311259
Last edited on
Very nice. Thank you. I was just elaborating on the logic of
String^ input = this->textBoxInput->Text;
and I had a thought that if I want to output into a read only text box it could look like:

String^ output = this->textBoxOutput->Text;

I'm sure there could be more to it, but that was just a thought I guess. Maybe its different. I'm still learning, but the more that I learn the more that I can elaborate on alterations if needed.
A very big question right now is: What H files do I need to include to make your conversion code work?
Generally speaking : That's good because I usually work with string & characters. :)
Comparing a Uppercase character is always faster than comparing a Lowercase character. (This is a good knowledge & concept) So I often use :
1
2
int GetCharCount(char *str, char chr){int nCount;//strupr(str);Uppercase(chr);
while(str && (*str)){if((*str) == chr)nCount++;str++;}return nCount;}

More convenient, to get the total amount of a specific character of a string instantly, I usually use :
(My favorite code) :
1
2
3
4
5
//short alphabet[256];
void ParsingString(char *str, short *alphabet){
for(int i = 0;i<256;i++)alphabet[i] = 0;//strupr(str);
while(str && (*str)){alphabet[(*str)]++;str++;}}
//These are created & included in my first big project (Developed alone & no network :)) 
Last edited on
Pages: 12