Форум программистов, компьютерный форум CyberForum.ru

Исключение символов из строки - C++

Восстановить пароль Регистрация
 
zu11u
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 5
23.11.2012, 16:53     Исключение символов из строки #1
Добрый день.
есть задача:
Дана строка символов. Группы символов, разделенные пробелами (одним или несколькими) и не содержащие пробелы внутри себя, будем называть словами. Исключить из строки слова, состоящие из символов русского и латинского алфавитов одновременно.

как я понимаю нужно разбить строку на слова ограниченные пробелами, и потом с каждым из них работаем.

я смог нарезать строчку при помощи strtok на отдельные слова, но как потом их обрабатывать?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
char instr[] ="bla bla  bla \ зеленеет к примеру | ghцуt ";
char * pch;
 
cout << instr << endl;
pch = strtok (InputString, " ");
while (pch != NULL)
{
 cout << pch << " :";
 pch = strtok (NULL, " ");
}
getch();
}
видел на форуме пример, но там была обработка потока, а тут указатель.
Ткните носом где копать?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.11.2012, 16:53     Исключение символов из строки
Посмотрите здесь:

Исключение из стркои символов последовательности, заключенной в кавычки C++
C++ Переворот строки. Необработанное исключение. Нарушения прав доступа
C++ строки С++(После каждого символов '.' вставить два пробела, подсчитать, сколько раз пара символов 'C+' стоит перед символом 'D')
C++ Удалить конец строки символов. Ввести кол-во удаляемых символов , вывести результат ,String ,задачка,С++
C++ Дана строка, состоящая из M попарно различных символов. Вывести все перестановки символов данной строки.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
24.11.2012, 16:12     Исключение символов из строки #2
Так как используются совместно русские и английские символы, лучше всего использовать вместо char wchar_t

Добавлено через 1 час 35 минут
Далее нужно объявить указатель и воспользоваться автоматическим приведением типов:
что то вроде:
C++
1
2
3
4
if( *cp_ptr >= 'A' && *cp_ptr <= 'z' )                                                       
     ++eng;                                                                                   
else                                                                                         
     ++rus;
Или просто
C++
1
2
3
4
if( *cp_ptr >= 65 && *cp_ptr <= 122 )                                                       
     ++eng;                                                                                   
else                                                                                         
     ++rus;
Добавлено через 20 часов 41 минуту
Вот функция, которая соответствует Вашему условию без использования сторонних функций типа isalpha() и strtok():
C++
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
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wchar.h>
 
void eng_rus( wchar_t *text );
 
int main( void )
{
    if( !setlocale(LC_ALL, "en_US.utf8") )
    EXIT_FAILURE;
    
    /* Это "не правильный вариан строки в стиле С.
       В "правильном" варианте строка должна оканчиваться
       символом конца строки \n. Поэтому этот нюанс
       мы учтём при написании функции. */
    wchar_t line[] = L"    Здесь долqжен   r   быть your,  text!";
    
    eng_rus( line );
    
    EXIT_SUCCESS;
}
 
void eng_rus( wchar_t *text )
{
    /*    if( !setlocale(LC_ALL, "en_US.utf8") )
      EXIT_FAILURE; */
    int i, j, f, eng, rus;
    
    for( i = 0; text[i] != '\0'; ++i );
    // создадим временный массива для обработки.
    wchar_t new_text[i+2]; // 2 нужно для символа конца файла и строки
    
    // уберём лишние пробелы
    for( j = i = 0; text[j] != '\0'; ) {
    if( text[j] == ' ' || text[j] == '\t' ) {
        new_text[i++] = ' ';
        while( text[++j] == ' ' );
    }
    else
        new_text[i++] = text[j++];
    }
    new_text[i] = '\n';
    new_text[++i] = '\0';
    
    // проверим на совместное использование русских
    // и английских символов
    for( i = j = f = rus = eng = 0; new_text[i] != '\0'; ++i) {
    if( new_text[i] != ' ' ) {
        j = i; // запоним счётчик
        while( new_text[i] != ' ' && new_text[i] != '\0') {
        if( new_text[i] <= 128 && new_text[i] >= 0 ) {
            ++eng;
            ++i;
        }
        else {
            ++rus;
            ++i;
        }
        }
    }
    if( rus && eng )
        rus = eng = 0;
    else {
        i = j;
        rus = eng = 0;
        while( new_text[i] != ' ' && new_text[i] != '\n' && new_text[i] != '\0') {
        text[f++] = new_text[i++];
        }
        if( new_text[i] == ' ')
        text[f++] = ' ';
    }
    }
    text[f] = '\n';
    text[++f] = '\0';
    
    i = 0;
    while( text[i] != '\0' )
    putwchar( text[i++] );
    
    return;
}
Добавлено через 31 минуту
Обнаружил логическую ошибку: если слово, например, состоит только из русских символов и после него идёт запятая( ASCII ), программа посчитает за комбинированное использование и не запишет слово в массив. Нужно заменить строки с 52-58:
C++
1
2
3
4
5
6
7
8
9
10
if( new_text[i] >= 'A' && new_text[i] <= 'z' ) {                                                
     ++eng;                                                                                      
     ++i;                                                                                        
}                                                                                               
else if( new_text[i] > 128 ) {                                                                  
     ++rus;                                                                                      
     ++i;                                                                                        
}                                                                                               
else                                                                                         
      ++i;
zu11u
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 5
26.11.2012, 17:29  [ТС]     Исключение символов из строки #3
Спасибо.
Но это у меня не сработало.
Вышла куча ошибок:
[C++ Error] Lab3.cpp(32): E2313 Constant expression required
[C++ Error] Lab3.cpp(77): E2451 Undefined symbol 'f'
[C++ Error] Lab3.cpp(77): E2275 { expected
[C++ Error] Lab3.cpp(78): E2238 Multiple declaration for 'text'
[C++ Error] Lab3.cpp(77): E2344 Earlier declaration of 'text'
[C++ Error] Lab3.cpp(78): E2275 { expected
[C++ Error] Lab3.cpp(80): E2303 Type name expected
[C++ Error] Lab3.cpp(81): E2040 Declaration terminated incorrectly
[C++ Error] Lab3.cpp(84): E2040 Declaration terminated incorrectly
[C++ Error] Lab3.cpp(85): E2190 Unexpected }

Я не стал с ними разбираться, но на примере Вашего кода, набросал следующий:

C++
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 <conio.h>
#include <iostream.h>
 
//---------------------------------------------------------------------------
 
char inp_str[] = "First secОnd , третий / forth";
char * pch;
char new_pch[40];
int eng = 0, rus = 0, e = 0, r = 0;
 
//---------------------------------------------------------------------------
 
int Char_Check(char x)
{
e = r = 0;
if(((x >= 'a') && (x <= 'z')||
    (x >= 'A') && (x <= 'Z')))
     e++;
 
if(((x >= 'а') && (x <= 'я')||
    (x >= 'А') && (x <= 'Я')))
    r++;
 
  return r;
  return e;
}
 
//---------------------------------------------------------------------------
 
int main()
{
  int i;
  cout << "Input string: " << inp_str << endl;
  pch = strtok (inp_str, " ");
  cout << "Output string:";
  while (pch != 0)
  {
    for (i = 0; pch[i] !=0; i++)
    {
    Char_Check(pch[i]);
 
    eng = eng + e;
    rus = rus + r;
    }
 
  if ((rus != 0) && (eng != 0)) cout << "" ;
  else cout << " " << pch;
 
  eng = rus = 0;
  pch = strtok (NULL, " ");
  }
  getch();
  }
Вроде работает. Только букву "ё" нужно будет добавить и оттестировать ещё пару раз.

Добавлено через 53 минуты
Немного переделал, для отображения русских символов в консоли.



C++
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
#include <conio.h>
#include <iostream.h>
#include <windows.h>
 
//---------------------------------------------------------------------------
 
char inp_str[] = "First,  м  secОnd fЁg третий / forth";
char * pch;
int eng = 0, rus = 0, e = 0, r = 0;
char buf[50];
 
 
int Char_Check(char x)
{
e = r = 0;
if(((x >= 'a') && (x <= 'z')||
    (x >= 'A') && (x <= 'Z')))
     e++;
 
if(((x >= 'а') && (x <= 'я') ||
    (x >= 'А') && (x <= 'Я') ||
    (x == 'ё') || (x == 'Ё')))
    r++;
 
  return r;
  return e;
}
 
void Print_Russ(char *str)
{
  CharToOem(str, buf);
  cout << buf;
}
 
//---------------------------------------------------------------------------
 
 
int main()
{
  setlocale(LC_ALL, "Russian");
  int i;
 
  cout << "Input string: ";
  Print_Russ(inp_str);
  cout << endl;
 
  pch = strtok (inp_str, " ");
  cout << "Output string:";
  while (pch != 0)
  {
 
    for (i = 0; pch[i] !=0; i++)
    {
    Char_Check(pch[i]);
 
    eng = eng + e;
    rus = rus + r;
    }
 
  if ((rus != 0) && (eng != 0)) cout << "" ;
  else
  {
  cout << " ";
  Print_Russ(pch);
  }
 
  eng = rus = 0;            
  pch = strtok (NULL, " "); 
 
  }
  getch();
  }
Кот Ангенс
 Аватар для Кот Ангенс
317 / 267 / 37
Регистрация: 24.05.2012
Сообщений: 629
26.11.2012, 17:39     Исключение символов из строки #4
Цитата Сообщение от zu11u Посмотреть сообщение
return r;
return e;
Простите, что?..
zu11u
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 5
26.11.2012, 18:01  [ТС]     Исключение символов из строки #5
Char_Check проверяет символы на соответствие условиям (русские символы от "а" до "я" + "ё") и английские (от "a" до "z")
и выводит r = 1 если это был русская буква либо e = 1 если это была английская буква.

строчки 56 - 57 суммирует количество русских и английских букв.
C++
1
2
eng += e;
rus += r;
Это нужно для проверки в строке 60.
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
26.11.2012, 19:48     Исключение символов из строки #6
Цитата Сообщение от zu11u Посмотреть сообщение
Я не стал с ними разбираться, но на примере Вашего кода, набросал следующий:
У меня компиляция на gcc прошла без ошибок.
zu11u
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 5
26.11.2012, 20:07  [ТС]     Исключение символов из строки #7
CodeGear и Borland C++ 6 ругались на 32 строку.
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
26.11.2012, 20:39     Исключение символов из строки #8
не совсем уверен, но кажется в МSVS и Borland вместо wchar_t используется WCHAR.
К томуже код
C++
1
2
3
if(((x >= 'a') && (x <= 'z')||
    (x >= 'A') && (x <= 'Z')))
     e++;
с точки зрения реализации правильный, но с другой стороны не совсем эстетичен. Он абсолютно идентичен следующему:
C++
1
2
3
if(((x >= 97) && (x <= 122)||
    (x >= 65) && (x <= 90)))
     e++;
как-то выглядит не сильно корректно, не правда ли?
А смысл в:
C++
1
2
3
4
if(((x >= 'а') && (x <= 'я') ||
    (x >= 'А') && (x <= 'Я') ||
    (x == 'ё') || (x == 'Ё')))
    r++;
вообще отпадает, если конечно вы не хотите использовать в ваше программе дополнительные языки по мимо английского и русского. Смысл заключается в том, что каждый символ имеет своё целочисленное значение. Английские символы и дополнительные знаки (типа пробела, ~, (, ), ] и т.п.) (ASCII) находятся в диапазоне от 0 до 128, а все остальные (unicode и т.п.) больше 128. Чтобы посмотреть значение символа в целочисленном представлении: в каком оно является на самом деле достаточно выполнить std::cout << (int)'A'; подключив заголовок <iostream> или printf( "%d", 'A' ); подключив заголовок <stdio.h>. В обоих случаях результат будет 65.
zu11u
0 / 0 / 0
Регистрация: 23.11.2012
Сообщений: 5
26.11.2012, 23:24  [ТС]     Исключение символов из строки #9
Вы были правы Borland спокойно принимал wchar_t.

Я пробовал использовать коды вместо букв, но английских символов принимались на ура, а с русскими возникли проблемы. Брал коды 128-159 160-175 224-241 взял по ссылке.
Но раз все коды не латинских букв идут за 128, то я ещё подпилю код, сократив немного ))). Спасибо за помощь.

Добавлено через 2 часа 23 минуты
Не знаю почему, но
это
C++
1
2
3
if(((x >= 'а') && (x <= 'я') ||
    (x >= 'А') && (x <= 'Я') ||
    (x == 'ё') || (x == 'Ё')))
заменяется этим
C++
1
2
if(((x >= -64) && (x <= -1) ||
    (x == -72) || (x == -88)))
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2012, 13:18     Исключение символов из строки
Еще ссылки по теме:

C++ Если строки одинаковы, объединить две строки, исключив из второй первые десять символов
C++ Получить из строк новую строку, содержащюю первые N1 символов строки S1 и последнии N2 символов строки S2
Текст, состоящий не более чем из 255 символов, разбить на строки длиной не более 50 символов в строке C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
27.11.2012, 13:18     Исключение символов из строки #10
Посмотреть поддерживаемую кодировку именно для вашей машини можно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>                                                                                              
#define SIZE 256                                                                                                
                                                                                                                
int main( void )                                                                                                
{                                                                                                               
    int i;                                                                                                      
                                                                                                                
    for( i = 0; i < SIZE; ++i )                                                                                 
        printf( "code %d; symbol %c\n", i, i );                                                                 
                                                                                                                
    return 0;                                                                                                   
}
Yandex
Объявления
27.11.2012, 13:18     Исключение символов из строки
Ответ Создать тему
Опции темы

Текущее время: 11:18. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru