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

строки. что-то тут не так - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
OcbMuHor
Заблокирован
04.06.2011, 00:35     строки. что-то тут не так #1
вот код
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
//Программа удаления из строки символов '0..9'
 
 
#include<iostream> // заголовыочный файл с описаниями функций ввод\вывод
#include<conio.h>  // заголовочный файл для создания текстового интерфейса в режиме MS-DOS
#include <string>  // заголовочный файл для класса string
 
int main()
{
    unsigned short i, k;  // объявление перемнных; беззнаковые целые числа.
    std::string str;      // объявление переменной для хранения строки
    std::cout << "VVEDITE STROKU" << std::endl;  // вывод на экран запроса строки
    std::getline(std::cin, str, '\n');           // ввод строки с клавиатуры
    std::cout << "UDALENIE IZ STROKI SIMVOLOV 0..9" << std::endl;  // без комментариев
    for (i = 0; i < str.size(); i++)  // цикл проверки символов на наличие 0..9
    {
        k = i;
        if (str[k] == 0x30) {str.erase(str.begin() + k); i = i--;} // проверка символов строки на соответствие
        if (str[k] == 0x31) {str.erase(str.begin() + k); i = i--;} // их шестнадцатиричным кодам в таблице ACSII
        if (str[k] == 0x32) {str.erase(str.begin() + k); i = i--;} // и удаление  
        if (str[k] == 0x33) {str.erase(str.begin() + k); i = i--;} // Операция декремента переменной "i" связана 
        if (str[k] == 0x34) {str.erase(str.begin() + k); i = i--;} // со сдвигом символов "влево" на место удаленного
        if (str[k] == 0x35) {str.erase(str.begin() + k); i = i--;} //
        if (str[k] == 0x36) {str.erase(str.begin() + k); i = i--;} //
        if (str[k] == 0x37) {str.erase(str.begin() + k); i = i--;} //
        if (str[k] == 0x38) {str.erase(str.begin() + k); i = i--;} //
        if (str[k] == 0x39) {str.erase(str.begin() + k); i = i--;} //
    }
    k = 0; i = 0;                                                  // обнуление памяти, отведенной переменным   
    std::cout << str <<std::endl;                                  // вывод на экран строки после удаления символов 0..9
    getch();                                                       // ожидание ввода с клавиатуры пользователем
    return 0;
}
Вопрос первый:
Компилятор возмущается тем что неправильно объявлена функция getch(), всё работает, но лучше бы уточнить как правильно.
Вопрос есть второй:
Программа работает, но при наборе символов кириллицей раз через раз влетает сбой и сообщение - индекс строки вне диапазона (string subscript out of range). Это при наборе абракадабры типа "ролукпг90384е3щ4е8г9рагк93за4р3489"
Интересует критика по эстетике и грамматике.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.06.2011, 00:35     строки. что-то тут не так
Посмотрите здесь:

C++ Что тут не так?
что тут не так??? C++
C++ Делаю сапёр. что тут не так????
Что тут не так? C++
Что тут не так? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 00:40     строки. что-то тут не так #2
C++
1
i = i--;
Что это должно было значить? По-моему это самое настоящее "поведение не определено".
OcbMuHor
Заблокирован
04.06.2011, 00:53  [ТС]     строки. что-то тут не так #3
Цитата Сообщение от grizlik78 Посмотреть сообщение
C++
1
i = i--;
Что это должно было значить? По-моему это самое настоящее "поведение не определено".
в случае выполнения условия при str[i]>str[i+1], str[i+1] не удаляется. При удалении символа надо снова пройти цикл с тем же индексом.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 00:56     строки. что-то тут не так #4
Спрошу по другому. Если, к примеру, до выполнения этой инструкции i равняется 5, то чему будет равно i после выполнения этой операции?
OcbMuHor
Заблокирован
04.06.2011, 01:05  [ТС]     строки. что-то тут не так #5
Цитата Сообщение от grizlik78 Посмотреть сообщение
Спрошу по другому. Если, к примеру, до выполнения этой инструкции i равняется 5, то чему будет равно i после выполнения этой операции?
ну это же видно зачем спрашивать? i=4, это гарантирует второй полный проход по i=5, а не только с момента выполнения условия, есть иной путь? я только за
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 01:10     строки. что-то тут не так #6
Ну мне же интересно, зачем простейшую операцию записывать так сложно
C++
1
i = i--;
там где надо просто
C++
1
i--;
и в результате код с неопределённым поведением.
Но проблема, разумеется, не в этом. А в том, что за одну итерацию может удаляться сразу несколько символов, а строка имеет большие шансы закончиться гораздо раньше, чем мы проверим не закончилась ли она
OcbMuHor
Заблокирован
04.06.2011, 01:21  [ТС]     строки. что-то тут не так #7
и все таки я только сейчас понял зачем i-- поставил. С каждым удаленным символом строка короче на 1 символ, следовательно верно i--
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 01:23     строки. что-то тут не так #8
i-- верно, а i = i-- не верно, хотя и может работать.
OcbMuHor
Заблокирован
04.06.2011, 01:28  [ТС]     строки. что-то тут не так #9
Все равно раз работает, раз ошибка
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 01:33     строки. что-то тут не так #10
Ну и раз уж всё-равно STL, то непонятно, зачем изобретать велосипед.
Вариант первый. Длинный.
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
//Программа удаления из строки символов '0..9'
 
 
#include<iostream> // заголовыочный файл с описаниями функций ввод\вывод
#include<conio.h>  // заголовочный файл для создания текстового интерфейса в режиме MS-DOS
#include <string>  // заголовочный файл для класса string
#include <algorithm>
 
int main()
{
    std::string str;      // объявление переменной для хранения строки
    std::cout << "VVEDITE STROKU" << std::endl;  // вывод на экран запроса строки
    std::getline(std::cin, str, '\n');           // ввод строки с клавиатуры
    std::cout << "UDALENIE IZ STROKI SIMVOLOV 0..9" << std::endl;  // без комментариев
    std::string::iterator beg = str.begin(), end = str.end();
    end = remove(beg, end, 0x30);
    end = remove(beg, end, 0x31);
    end = remove(beg, end, 0x32);
    end = remove(beg, end, 0x33);
    end = remove(beg, end, 0x34);
    end = remove(beg, end, 0x35);
    end = remove(beg, end, 0x36);
    end = remove(beg, end, 0x37);
    end = remove(beg, end, 0x38);
    end = remove(beg, end, 0x39);
    str.erase(end, str.end());
    std::cout << str <<std::endl;                                                              // вывод на экран строки после удаления символов 0..9
    getch();                                                                                                           // ожидание ввода с клавиатуры пользователем
    return 0;
}
Вариант второй, короткий
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Программа удаления из строки символов '0..9'
 
 
#include<iostream> // заголовыочный файл с описаниями функций ввод\вывод
#include<conio.h>  // заголовочный файл для создания текстового интерфейса в режиме MS-DOS
#include <string>  // заголовочный файл для класса string
#include <algorithm>
 
int main()
{
    std::string str;      // объявление переменной для хранения строки
    std::cout << "VVEDITE STROKU" << std::endl;  // вывод на экран запроса строки
    std::getline(std::cin, str, '\n');           // ввод строки с клавиатуры
    std::cout << "UDALENIE IZ STROKI SIMVOLOV 0..9" << std::endl;  // без комментариев
    std::string::iterator beg = str.begin(), end = str.end();
    end = remove_if(beg, end, isdigit);
    str.erase(end, str.end());
    std::cout << str <<std::endl;                                                              // вывод на экран строки после удаления символов 0..9
    getch();                                                                                                           // ожидание ввода с клавиатуры пользователем
    return 0;
}
Добавлено через 1 минуту
Короткий вариант получился всё-равно слишком длинным, потому что переделывался из длинного

Добавлено через 2 минуты
Вот так должно было быть
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Программа удаления из строки символов '0..9'
 
 
#include<iostream> // заголовыочный файл с описаниями функций ввод\вывод
#include<conio.h>  // заголовочный файл для создания текстового интерфейса в режиме MS-DOS
#include <string>  // заголовочный файл для класса string
#include <algorithm>
 
int main()
{
    std::string str;      // объявление переменной для хранения строки
    std::cout << "VVEDITE STROKU" << std::endl;  // вывод на экран запроса строки
    std::getline(std::cin, str, '\n');           // ввод строки с клавиатуры
    std::cout << "UDALENIE IZ STROKI SIMVOLOV 0..9" << std::endl;  // без комментариев
    str.erase(remove_if(str.begin(), str.end(), isdigit), str.end());
    std::cout << str <<std::endl;                                                              // вывод на экран строки после удаления символов 0..9
    getch();                                                                                                           // ожидание ввода с клавиатуры пользователем
    return 0;
}
OcbMuHor
Заблокирован
04.06.2011, 01:40  [ТС]     строки. что-то тут не так #11
Спасибо, ничего я не изобретаю впервые столкнулся с символьными данными вот начинаем понимать по чуть чуть
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 01:45     строки. что-то тут не так #12
Ну а по поводу исходной программы, я ошибку обозначил:
Цитата Сообщение от grizlik78 Посмотреть сообщение
Но проблема, разумеется, не в этом. А в том, что за одну итерацию может удаляться сразу несколько символов, а строка имеет большие шансы закончиться гораздо раньше, чем мы проверим не закончилась ли она
Слегка туманно, но если над этим подумать, то ошибка найдётся
OcbMuHor
Заблокирован
04.06.2011, 02:11  [ТС]     строки. что-то тут не так #13
grizlik78, Кстати Ваш код тоже работает через раз. При наборе длинной абракадабры кириллицей сбой.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 02:15     строки. что-то тут не так #14
Первый? Второй? Оба?
Что за компилятор?

Добавлено через 1 минуту
И в чём выражается сбой?
OcbMuHor
Заблокирован
04.06.2011, 02:19  [ТС]     строки. что-то тут не так #15
Цитата Сообщение от grizlik78 Посмотреть сообщение
Первый? Второй? Оба?
Что за компилятор?

Добавлено через 1 минуту
И в чём выражается сбой?
третий
expression: (unsigned)(c+1)<=256

Как я понимаю, это потому что кириллицы просто не в ASCII
среда MSDN 10.0
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 02:23     строки. что-то тут не так #16
А, ну подозреваю, что проверка срабатывает в функции isdigit. Ну это просто для примера, вместо этой функции можно определить и использовать свой предикат.
OcbMuHor
Заблокирован
04.06.2011, 02:28  [ТС]     строки. что-то тут не так #17
в итоге мой код эффективнее Вашего, и спасибо большое за участие. Сейчас исправил на i-- , работает...
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
04.06.2011, 02:40     строки. что-то тут не так #18
А не должен работать, если строка оканчивается цифрой, кроме 9
Вообще, раз у кириллических символов код оказывается больше 256, то видимо используются "широкие" символы (хотя странно). Можно попробовать заменить isdigit на iswdigit, но тут я уже ни в чём не уверен. Даже в том, что оно скомпилируется
А в чём выражается большая эффективность?

Добавлено через 9 минут
Впрочем, у меня компилируется и работает.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.06.2011, 02:41     строки. что-то тут не так
Еще ссылки по теме:

Поясните чайнику что тут не так C++
C++ Что тут не так?
Подскажите,что тут не так? C++

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

Или воспользуйтесь поиском по форуму:
OcbMuHor
Заблокирован
04.06.2011, 02:41  [ТС]     строки. что-то тут не так #19
Цитата Сообщение от grizlik78 Посмотреть сообщение
А в чём выражается большая эффективность?
Только не смейтесь))) работает. Ну я так понимаю что в данной задаче можно ресурсом пренебречь, а дальше так не прокатит В любом случае начало строкам положено.
Сидит программист пишет код, подходит сын: "папа, а почему солнце светит?" "не трогай! светит и хорошо"
Yandex
Объявления
04.06.2011, 02:41     строки. что-то тут не так
Ответ Создать тему
Опции темы

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