Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/26: Рейтинг темы: голосов - 26, средняя оценка - 4.62
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81

Удалить из строки слова, содержащие цифры

17.02.2013, 21:22. Показов 5624. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
[MFC] Помогите пожалуйста кто-нибудь, как разделять массив строк, используя CString, очень прошу помощи Через консоль подобное давно бы сделал
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.02.2013, 21:22
Ответы с готовыми решениями:

Дана строка, удалить слова содержащие цифры
что то не работает она у меня, помогите. #include <string.h> #include <ctype.h> #include <iostream.h> #define DELIM "...

Поместить в начало строки слова, содержащие только цифры, а затем – все остальные слова
Строка состоит из слов, разделенных ровно одним пробелом, пробелов перед первым и после последнего слова нет. Поместить в начало строки...

Удалить из строки слова, содержащие четное кол-во символов. Слова в строке разделены одним или несколькими пробелами. По
Удалить из строки слова, содержащие четное кол-во символов. Слова в строке разделены одним или несколькими пробелами. Помогите...

35
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
18.02.2013, 22:27
CString - это просто обертка над обычным массивом (в частности, позволяет ему динамически расти).

Посмотрите в MSDN методы класса CString - там есть доступ по индексу к элементу строки итп.

Все, что вы можете сделать с обычной строкой типа char* (и даже больше), можете сделать и с CString - ценой не слишком больших накладных расходов.

Возьмите ваш код на C и просто переведите его "в MFC" - заглядывая в описание из MSDN. Получив первый опыт, займетесь оптимизацией.

На сайтах типа codeguru.com / codeproject.com вы можете найти исходники десятков примеров токенайзеров и парсеров строк именно на MFC, но будет больше пользы, если сделаете это самостоятельно.
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
19.02.2013, 05:11  [ТС]
Цитата Сообщение от gazlan Посмотреть сообщение
CString - это просто обертка над обычным массивом (в частности, позволяет ему динамически расти).

Посмотрите в MSDN методы класса CString - там есть доступ по индексу к элементу строки итп.

Все, что вы можете сделать с обычной строкой типа char* (и даже больше), можете сделать и с CString - ценой не слишком больших накладных расходов.

Возьмите ваш код на C и просто переведите его "в MFC" - заглядывая в описание из MSDN. Получив первый опыт, займетесь оптимизацией.

На сайтах типа codeguru.com / codeproject.com вы можете найти исходники десятков примеров токенайзеров и парсеров строк именно на MFC, но будет больше пользы, если сделаете это самостоятельно.
спасибо, уже на msdn нашел все, что нужно
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
26.02.2013, 13:36  [ТС]
Здравствуйте ещё раз, я всё по той же проблеме, с Tolenize разобрался...но не понимаю, какой цикл внутрь вводить надо. Вот код функции обработки:

Кликните здесь для просмотра всего текста
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
bool CMainDlg::ProcessFiles(CString sFileIn, CString sFileOut)
{
    _wsetlocale(LC_CTYPE, _T("rus"));
    CFile fileIn;
            
    CString str;
    CString str2;
    CString sMsg;  
    CString FileRead[256];
    CString numbers = (L"1234567890");
    CString h = (L"");
 
    int n(0),count(0);
 
 
    if(!fileIn.Open(sFileIn, CFile::modeRead))
    {
        sMsg.Format(L"Не могу открыть файл %s", sFileIn);
        MessageBox(sMsg, L"Ошибка", MB_OK | MB_ICONERROR);
        return false;
    }
    else
    {
        fileIn.Seek(2, CFile::begin);
 
        ULONGLONG size = fileIn.GetLength();
        if (!fileIn.Read(str.GetBufferSetLength((size - 2) / 2), size - 2))
        {
            MessageBox(L"Ошибка чтения строки из файла.", L"Ошибка", MB_OK | MB_ICONSTOP);
            return false;
        }
        str.ReleaseBuffer();
 
        int start(0);
        CString word = str.Tokenize(L" ", start);
 
        while(!word.IsEmpty())
        {
            TRACE(L"%s ", word);
            word = str.Tokenize(L" ", start);
        }              
        TRACE(L"\n");
    }
 
    CStdioFile fileOut;
 
    if(!fileOut.Open(sFileOut, CFile::modeWrite | CFile::modeCreate))
    {
        sMsg.Format(L"Не могу открыть файл результата %s", sFileOut);
        MessageBox(sMsg, L"Ошибка", MB_OK | MB_ICONERROR);
        return false;
    } 
    else
    {
        fileOut.WriteString(str);
    }
    return true;
}
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
26.02.2013, 17:30
А при чем тут операции с файлами? Да еще такие странные? Если вам нужно читать из файла построчно, используйте fgets(). У CFile нет методов форматированного ввода.

Прочитанную строку помещаете в CString и работаете с ней методами этого класса. Если нужен цикл - то самое место для него здесь - в tokenizer().

tokenizer, очевидно, может быть устроен двояко: либо он возвращает очередной токен, либо список всех токенов (первый вариант, обычно, проще). Сам токен может быть либо копией части входной строки, либо парой (tupple) вида (Ptr,Size) или (Ofs,Size). Наивный вариант с копированием, обычно, проще.

Обратную запись также можно выполнить через fputs(). В любом случае, неформатированный I\O посредством CFile - самый неудобный для вас вариант.
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
26.02.2013, 18:54  [ТС]
gazlan, использую CFileStdio, потому что по заданию, надо считывать из файла, обрабатывать и записывать результат в выходной файл. Никаких отстроненний нельзя делать
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
26.02.2013, 19:32
А в файле у вас при этом одна-единственная строка (та, что требует обработки) или произвольный набор строк?

Во втором случае, вам придется, сначала, огранизовать собственное "форматированное чтение" - выборку отдельной строки из файла.

Вы уверены, что заданием установлено ограничение: использовать только CFile?
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
26.02.2013, 20:38  [ТС]
gazlan, дан текст, в файле input.txt , нужно вывести результат в output.txt, в тексте не произвольный текст, а я сам его написал, ну хотя можно написать любой другой. Можно использовать CFile и CStdioFile
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
26.02.2013, 22:08
ОК. У CStdioFile есть методы ReadString()/WriteString(). Осталось написать токенайзер :-)

[Lyrics]
Одна подкова уже есть, осталось найти еще три подковы и лошадь. (испанск)
[/Lyrics]
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
27.02.2013, 04:22  [ТС]
gazlan, я в коде уже написал запись и вывод, все нормально читает и отлично записывается. Я писал изначально, чтобы помочь мне написать токенайзер...
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
27.02.2013, 04:39
Цитата Сообщение от dmmax Посмотреть сообщение
gazlanпомочь мне написать токенайзер
Ну, покажите, что делаете - а здесь вам расскажут, почему все это неправильно :-)
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
27.02.2013, 09:49  [ТС]
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
bool CMainDlg::ProcessFiles(CString sFileIn, CString sFileOut)
{
    _wsetlocale(LC_CTYPE, _T("rus"));//подключил рус.яз.
    CFile fileIn;//создал файл для приема
            
    CString str;//создал строку
    CString str2;//создал вторую строку, пока не знаю для чего, но хотел что-то с ней сделать :)
    CString sMsg;//строка, которая опевещает об ошибке
    CString FileRead[256];//строка для чтения
    CString numbers = (L"1234567890");//этим я не пользуюсь, до этого хотел просто в цикле найти слова с цифрами и                           удалить, не получилось...
    CString h = (L"");//все для того же цикла, хотел, чтобы если встретилось слово с числом, то заменить его на пустое значение
 
    int n(0),count(0);//n и count для того же цикла хотел использовать, n число символов, count - число слов.
 
    if(!fileIn.Open(sFileIn, CFile::modeRead))//проверка, есть ли файл.
    {
        sMsg.Format(L"Не могу открыть файл %s", sFileIn);
        MessageBox(sMsg, L"Ошибка", MB_OK | MB_ICONERROR);
        return false;
    }
    else//если есть, то...
    {
        fileIn.Seek(2, CFile::begin);//ищем начало файла, на сколько я понял..
 
        ULONGLONG size = fileIn.GetLength();//создает переменную, чтобы узнать длину текста в файле.
        if (!fileIn.Read(str.GetBufferSetLength((size - 2) / 2), size - 2))//проверка
        {
            MessageBox(L"Ошибка чтения строки из файла.", L"Ошибка", MB_OK | MB_ICONSTOP);
            return false;
        }
        str.ReleaseBuffer();//на сколько я понял это освобождение буфера 
 
        int start(0);
        CString word = str.Tokenize(L" ", start);//разбивает строки на слова, т.е. если встретит " ", т.е. пробел, то будет читать следующее слово
 
        while(!word.IsEmpty())//читает до тех пор, пока не встретит пусто
        {
            TRACE(L"%s ", word);//вывод слов
            word = str.Tokenize(L" ", start);
        }              
        TRACE(L"\n");// перенос на следующую строку
    }
 
    CStdioFile fileOut;//файл для вывода
 
    if(!fileOut.Open(sFileOut, CFile::modeWrite | CFile::modeCreate))//проверка на наличие вайла, если не запишет, то создаст его.
    {
        sMsg.Format(L"Не могу открыть файл результата %s", sFileOut);
        MessageBox(sMsg, L"Ошибка", MB_OK | MB_ICONERROR);
        return false;
    } 
    else
    {
        fileOut.WriteString(str);//запись в файл
    }
    return true;
}
Добавлено через 34 секунды
хочу так же добавить, что не сильно разбираюсь в MFC, мог что-то напутать....
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
27.02.2013, 12:26
Цитата Сообщение от dmmax Посмотреть сообщение
не сильно разбираюсь в MFC, мог что-то напутать
Еще никто не родился с готовым знанием MFC - всем пришлось учиться.

fileIn.Seek() - это не требуется. Используйте CStdioFile.ReadString()

ReleaseBuffer() - это вообще ни к чему: освободив буфер, объект класса полностью теряет контроль над ним и возлагает его на программиста. Вам это надо?

str.Tokenize() - А что, в классе CString уже есть такой метод? Используйте FindOneOf() для поиска разделителей (это не только - и не обязательно - пробел, но еще табуляция, знаки препинания, спецсимволы итп).

Правильный подход для вашего случая - явно перечислить все допустимые в слове символы (например, дефис и апостроф допустимы: {из-за}, {О'Генри} - это корректные слова, а двойная кавычка - нет. {об"ект} - это будет, в вашем случае, не одно слово).

C++
1
while(!word.IsEmpty()) // читает до тех пор, пока не встретит пусто
Примерно так. Детали будут зависеть от реализации токенайзера.
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
27.02.2013, 13:06  [ТС]
gazlan, все 3 кода написал мне учитель...мне оставалось только условие в Tokenize сделать...сейчас вы мне предлагаете все убрать Я могу копию сделать и попробывать, но так и так мне нужно само условие...не понимаю, как заменить слово пустым значением. Знаю, что в программирование нет ничего невозможного, поэтому помогите пожалуйста сделать условие...не надо менять код
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
27.02.2013, 14:34
Цитата Сообщение от dmmax Посмотреть сообщение
gazlan
не надо менять код
Гм. Вот это точно невозможно. Ну, нет у CString метода Tokenize(): http://msdn.microsoft.com/en-u... 60%29.aspx

Если вам нужно, чтобы Tokenize() было методом класса, вам придется написать собственный.

Алго может выглядеть так:
C++
1
2
3
4
5
6
7
. Устанавливаем указатель позиции в 0
. Перебираем в цикле символы строки до первой "небуквы" или конца входного буфера
. Если первая найденная "небуквы" находится в позиции маркера (0), значит строка начинается с разделителя, который надо пропустить
. В этом случае перебираем в цикле символы строки до первой "буквы" или конца входного буфера
. Если буфер кончился, значит в нем ничего, кроме разделителей не было. Возвращаем пустую строку.
. При удачном раскладе (какие-то идущие подряд буквы найдены) у нас есть указатель на начало подстроки (или 0, или за последней "небуквой" и на конец подстроки - перед первой за ней "небуквой")
. Используя эти два указателя (позиции подстроки в строке), копируем в выходной буфер символы подстроки, завершаем корректно нулем, устанвливаем указатель позиции за концом найденной подстроки, возвращаем выходной буфер.
Вызываем этот код в цикле до получения пустой строки - признака конца буфера.

Важно: "указатель позиции" должен сохранять свое значение между вызовами Tokenize().

Если это член класса Tokenizer, условие будет выполнено автоматически.

Если Tokenize() будет реализован как обычная функция, необходимо, чтобы эта переменная имела класс памяти static или находилась в охватывающем блоке.
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
27.02.2013, 15:33  [ТС]
gazlan, если бы она не работала, то она не работала, а она на самом деле разбивает на слова
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
27.02.2013, 15:51
Цитата Сообщение от dmmax Посмотреть сообщение
gazlan
если бы она не работала, то она не работала, а она на самом деле разбивает на слова
Oops!

Не подумал. Я предпочитаю старую шестерку (из-за компактного кода), а в более новых версиях MFC CStringT::Tokenize() действительно есть.


Well. Судя по описанию
C++
1
CStringT Tokenize(PCXSTR pszTokens,int& iStart) const;
она работает именно по алго, изложенному выше.

Тогда что еще осталось?
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
27.02.2013, 15:52  [ТС]
gazlan, цикл удаления слов с цифрами внутри while
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
27.02.2013, 17:05
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
while (true)
{
   Str.Tokenize(...);
 
   if (Str.IsEmpty()) 
   {
      // End of String
      break;
   }
 
   if (Str.FindOneOf("0123456789") != -1)
   {
      // Contain digits - remove
      Str = _T("");
   }
   
   ...
 
   // Write output
   CStdioFile.WriteString((LPCTSTR)Str);
}
Добавлено через 54 минуты
Вот еще, не сообразил - запись тоже должна быть одной строкой.

Поэтому вводим еще промежуточную строку - аккумулятор, накапливаем в ней строку, а потом записываем.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CString     sAcc = _T("");
 
while (true)
{
   Str.Tokenize(...);
 
   if (Str.IsEmpty()) 
   {
      // End of String
      break;
   }
 
   if (Str.FindOneOf("0123456789") == -1)
   {
      // No digits - append
      sAcc += Str;
   }
}
 
// Write output
CStdioFile.WriteString((LPCTSTR)sAcc);
0
 Аватар для dmmax
0 / 0 / 0
Регистрация: 24.09.2012
Сообщений: 81
27.02.2013, 17:35  [ТС]
gazlan, у меня VS 2012, findoneof просит передать 3 параметра
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int start(0);
        CString word = str.Tokenize(L" ", start);
 
        while(!word.IsEmpty())
        {
        //  TRACE(L"%s ", word);
            if(word.FindOneOf("1234567890") != -1)
                        {
                            word = _T("");
                        }
 
            word = str.Tokenize(L" ", start);
        }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.02.2013, 17:35
Помогаю со студенческими работами здесь

Удалить из введеной с клавиатуры строки слова, содержащие менее 2-х символов 'а'
Помогите, пожалуйста, написать программу.. Удалить из введеной с клавиатуры строки слова, содержащие менее 2-х символов 'а'.

Строки (из заданной последовательности слов удалить слова, содержащие числа) )
Из заданной последовательности слов удалить слова, содержащие числа.

Удалить из строки все слова, начинающиеся с цифры
Дана строка символов, состоящая из слов, слова разделены между собой пробелами. - удалить из строки все слова, начинающиеся с цифры. ...

Удалить из введенной с клавиатуры строки первые 2 слова, если это цифры
Написать программу, которая удаляет из введенной с клавиатуры строки первые 2 слова если это цифры.

Удалить из введенной с клавиатуры строки первые 2 слова, если это цифры
Помогите написать программу, которая удаляет из введенной с клавиатуры строки первые 2 слова если это цифры.


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru