Заблокирован
1

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

04.06.2011, 00:35. Показов 1539. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
вот код
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"
Интересует критика по эстетике и грамматике.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.06.2011, 00:35
Ответы с готовыми решениями:

Что тут не так?
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; bool is_it(char *); int main(){...

Что тут не так?
# include &lt;iostream&gt; using namespace std; int number ; int department ; char name1 ; char...

Что тут не так?
Не понимаю - почему программа не работает... Если все string Заменить на массивы char, то всё...

Что тут не так?
Всем привет! Объясните пожалуйста почему этот код работает некорректно: while (count--) { ...

18
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.06.2011, 00:40 2
C++
1
i = i--;
Что это должно было значить? По-моему это самое настоящее "поведение не определено".
0
Заблокирован
04.06.2011, 00:53  [ТС] 3
Цитата Сообщение от grizlik78 Посмотреть сообщение
C++
1
i = i--;
Что это должно было значить? По-моему это самое настоящее "поведение не определено".
в случае выполнения условия при str[i]>str[i+1], str[i+1] не удаляется. При удалении символа надо снова пройти цикл с тем же индексом.
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.06.2011, 00:56 4
Спрошу по другому. Если, к примеру, до выполнения этой инструкции i равняется 5, то чему будет равно i после выполнения этой операции?
0
Заблокирован
04.06.2011, 01:05  [ТС] 5
Цитата Сообщение от grizlik78 Посмотреть сообщение
Спрошу по другому. Если, к примеру, до выполнения этой инструкции i равняется 5, то чему будет равно i после выполнения этой операции?
ну это же видно зачем спрашивать? i=4, это гарантирует второй полный проход по i=5, а не только с момента выполнения условия, есть иной путь? я только за
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.06.2011, 01:10 6
Ну мне же интересно, зачем простейшую операцию записывать так сложно
C++
1
i = i--;
там где надо просто
C++
1
i--;
и в результате код с неопределённым поведением.
Но проблема, разумеется, не в этом. А в том, что за одну итерацию может удаляться сразу несколько символов, а строка имеет большие шансы закончиться гораздо раньше, чем мы проверим не закончилась ли она
0
Заблокирован
04.06.2011, 01:21  [ТС] 7
и все таки я только сейчас понял зачем i-- поставил. С каждым удаленным символом строка короче на 1 символ, следовательно верно i--
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.06.2011, 01:23 8
i-- верно, а i = i-- не верно, хотя и может работать.
0
Заблокирован
04.06.2011, 01:28  [ТС] 9
Все равно раз работает, раз ошибка
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
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;
}
0
Заблокирован
04.06.2011, 01:40  [ТС] 11
Спасибо, ничего я не изобретаю впервые столкнулся с символьными данными вот начинаем понимать по чуть чуть
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.06.2011, 01:45 12
Ну а по поводу исходной программы, я ошибку обозначил:
Цитата Сообщение от grizlik78 Посмотреть сообщение
Но проблема, разумеется, не в этом. А в том, что за одну итерацию может удаляться сразу несколько символов, а строка имеет большие шансы закончиться гораздо раньше, чем мы проверим не закончилась ли она
Слегка туманно, но если над этим подумать, то ошибка найдётся
0
Заблокирован
04.06.2011, 02:11  [ТС] 13
grizlik78, Кстати Ваш код тоже работает через раз. При наборе длинной абракадабры кириллицей сбой.
0
Эксперт С++
2381 / 1665 / 279
Регистрация: 29.05.2011
Сообщений: 3,399
04.06.2011, 02:15 14
Первый? Второй? Оба?
Что за компилятор?

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

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

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

Добавлено через 9 минут
Впрочем, у меня компилируется и работает.
0
Заблокирован
04.06.2011, 02:41  [ТС] 19
Цитата Сообщение от grizlik78 Посмотреть сообщение
А в чём выражается большая эффективность?
Только не смейтесь))) работает. Ну я так понимаю что в данной задаче можно ресурсом пренебречь, а дальше так не прокатит В любом случае начало строкам положено.
Сидит программист пишет код, подходит сын: "папа, а почему солнце светит?" "не трогай! светит и хорошо"
0
04.06.2011, 02:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.06.2011, 02:41
Помогаю со студенческими работами здесь

Да что тут не так?
По идее у меня должны выводится положительные числа #include &lt;iostream&gt; using namespace std;...

что тут не так???
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;iostream&gt; #include &lt;math.h&gt; #define size int...

Подскажите,что тут не так?
# include &lt;iosDream.h&gt; int main { int counter != 0 ; loop; counter ++ ; cout&lt;&lt;...

Поясните чайнику что тут не так
Всем доброго времени суток. Вот как уже месяц учусь на компьютерного инженера. И всё было...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru