String Turkish character problem

Hello, first of all sorry for my english.

I want to write a program that prints the number of some special letters in the entered text.

For example specialleters = 'a', 'ü', 'ı', 'i'.

My text = 'bugün günlerden cumartesi.';

Number of special letters:
a = 1
ü = 2
ı = 0
i = 1

But string doesn't read Turkish characters.

For Example my char is "Ü" but programs convert "Ÿ".

My code :
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
#include "pch.h"
#include <iostream>
#include <string>
#include <locale.h>

using namespace std;

int main()
{
	setlocale(LC_ALL, "Turkish");


	string str;
	getline(cin, str);
	char sesliHarfler[] = {'a','e','ı','i','o','ö','u', 'ü'};
	int seslisayisi[] = {0,0,0,0,0,0,0,0};
	int toplam = 0;

	//Büyük harfler küçük harflere çevriliyor.
	for (int i = 0; i < str.length(); i++) { // i=0'dan başlayıp girilen metinin harf sayısı kadar dönüyor.
		str[i] = tolower(str[i]);

		for (int j = 0; j < 8; j++) {
			if (str[i] == sesliHarfler[j])
			{
				seslisayisi[j] ++;
				toplam++;

			}
		}

	}


	for (int i = 0; i < 8; i++) {
		cout << sesliHarfler[i] << " " << seslisayisi[i] << endl;
	}

	cout << toplam << " tane ünlü var" << endl;

	system("pause");
	return 0;
}



Thanks.


Last edited on
If you are on windows, try using:

1
2
#include <io.h>
#include <fcntl.h> 

with
1
2
_setmode(_fileno(stdout), _O_U16TEXT);
std::wcout << L"text here";


Also setlocale(LC_ALL, "Turkish") does nothing, you should check if it returns NULL to see if the call worked (it didn't), or use C++'s std::locale for an exception.
Last edited on
First of all, use code tags: http://www.cplusplus.com/articles/jEywvCM9/

Is it necessary to use "tolower" function? ASCII codes may be better for these characters.

Try this:
1
2
3
4
5
for (int i = 0; i < str.length(); i++)
{
	if (str[i] == 'A' || str[i] == 'a') sesliSayisi[0]++;
	else if (str[i] == 'E' || str[i] == 'e') sesliSayisi[1]++;
}
They didn't work. My text is "Kısır ve çorba ne güzel gider.". But Visual Studio sees http://i65.tinypic.com/15cefdk.png.
With using wcout, you could also use wcin for wide input.

You may be taking in a windows legacy code page (varies from locale to locale, only 256 chars no multibyte), and converting it to wide char in a for loop (which is horrible, and everything past 127 is different).

Also I forgot that SetConsoleOutputCP(CP_UTF16); does the same thing.

If you want to incorportate utf-8 to your code, you could try to use codecvt, or windows style MultiByteToWideChar, or use the utf8cpp library.

You should also note that tolower has a towlower version for wide strings.

Don't forget to check the return type of _setmode or SetConsoleOutputCP(CP_UTF16) or towlower.

And if you still have problems show your code.
Try using wchar_t instead of char, and also wstring, wcin and wcout.
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
#include <iostream>
#include <string>
#include <locale.h>

using namespace std;

int main()
{
	setlocale(LC_ALL, "Turkish");

	wstring str;
	getline(wcin, str);
	wchar_t sesliHarfler[] = { L'a',L'e',L'ı',L'i',L'o',L'ö',L'u', L'ü' };
	int seslisayisi[] = { 0,0,0,0,0,0,0,0 };
	int toplam = 0;

	//Büyük harfler küçük harflere çevriliyor.
	for (int i = 0; i < str.length(); i++) { // i=0'dan başlayıp girilen metinin harf sayısı kadar dönüyor.
		str[i] = towlower(str[i]);

		for (int j = 0; j < 8; j++) {
			if (str[i] == sesliHarfler[j])
			{
				seslisayisi[j] ++;
				toplam++;

			}
		}

	}


	for (int i = 0; i < 8; i++) {
		wcout << sesliHarfler[i] << L" " << seslisayisi[i] << endl;
	}

	wcout << toplam << L" tane ünlü var" << endl;

	system("pause");
	return 0;
}
fcantoro, problem still continue. Poteto, I am not good at c++ this is my homework for school. My code:

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

#include "pch.h"
#include <iostream>
#include <string>
#include <locale.h>

using namespace std;

int main()
{
	setlocale(LC_ALL, "Turkish");

	wstring str;
	getline(wcin, str);
	wchar_t sesliHarfler[] = { L'a',L'e',L'ı',L'i',L'o',L'ö',L'u', L'ü' };
	int seslisayisi[] = { 0,0,0,0,0,0,0,0 };
	int toplam = 0;

	//Büyük harfler küçük harflere çevriliyor.
	for (int i = 0; i < str.length(); i++) { // i=0'dan başlayıp girilen metinin harf sayısı kadar dönüyor.
		str[i] = towlower(str[i]);

		for (int j = 0; j < 8; j++) {
			if (str[i] == sesliHarfler[j])
			{
				seslisayisi[j] ++;
				toplam++;

			}
		}

	}


	for (int i = 0; i < 8; i++) {
		wcout << sesliHarfler[i] << L" " << seslisayisi[i] << endl;
	}

	wcout << toplam << L" tane ünlü var" << endl;

	system("pause");
	return 0;
}
1
2
3
4
#include <windows.h> //use lean and mean if you don't like bloat
//... in main
if (!SetConsoleCP(CP_UTF16)){return 1;}
if (!SetConsoleOutputCP(CP_UTF16)){return 2;}


I am not sure if your problem is graphical or logical, there is a lot of technical information I do not know about your situation, but if you just put the input inside the code it will work.

edit: I mean like, if you skip wcin completely and hard code the input, your code works fine logically.

Perhaps you need to start CMD with /U after it in the prompt in RUN or create a shortcut with /U in the location prompt. This may fix input corruption if that is the problem, and maybe even change the terminal font...

But then again, arf's answer is also correct, I was making you do all this work because I am assuming that you don't have a turkish locale on your computer somehow (even though it wouldn't make sense to why you don't have it, since your visual studios has turkish text, but if you did, your code should've worked fine in the first place).

ALSO I forgot to mention that towlower is in C++'s version of locale, so remove the .h from it.
Last edited on
Did't work on Visual Studio.
If isn't necessary to use tolower function, you can count each vowel by using ASCII codes of characters.

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
#include <iostream>
#include <string>

using namespace std;

int main()
{
	setlocale(LC_ALL, "Turkish");

	string str;
	cout << "Cümle girin:";
	getline(cin, str);
	char sesliHarfler[] = { 'a','e','ı','i','o','ö','u','ü' };
	int sesliSayisi[] = { 0,0,0,0,0,0,0,0 };
	int toplam = 0;

	// Counting number of each novel
	// If "tolower" functions works, you can use in loop
	for (int i = 0; i < str.length(); i++)
	{
		if (str[i] == 'A' || str[i] == 'a') sesliSayisi[0]++;
		else if (str[i] == 'E' || str[i] == 'e') sesliSayisi[1]++;
		else if (str[i] == 'I' || str[i] == char(141)) sesliSayisi[2]++;	// char(141) = 'ı'
		else if (str[i] == char(152) || str[i] == 'i') sesliSayisi[3]++;	// char(152) = 'İ'
		else if (str[i] == 'O' || str[i] == 'o') sesliSayisi[4]++;
		else if (str[i] == char(153) || str[i] == char(148)) sesliSayisi[5]++;	// char(153) = 'Ö' and char(148) = 'ö'
		else if (str[i] == 'U' || str[i] == 'u') sesliSayisi[6]++;
		else if (str[i] == char(129) || str[i] == char(154)) sesliSayisi[7]++;	// char(129) = 'Ü' and char(154) = 'ü'
	}

	// Printing number of each vowel
	for (int i = 0; i < 8; i++)
	{
		cout << sesliHarfler[i] << " = " << sesliSayisi[i] << endl;
	}

	// Counting all vowels
	for (int i = 0; i < 8; i++)
	{
		toplam += sesliSayisi[i];
	}

	cout << "Toplam " << toplam << " tane ünlü var" << endl;

	system("pause");
	return 0;
}


Text: AAaaEEeeIIııİİiiOOooÖÖööUUuuÜÜüü
Output:
Cümle girin:AAaaEEeeIIııİİiiOOooÖÖööUUuuÜÜüü
a = 4
e = 4
ı = 4
i = 4
o = 4
ö = 4
u = 4
ü = 4
Toplam 32 tane ünlü var


Hope that helps,
arf
Last edited on
arf, thank you. :)
Topic archived. No new replies allowed.