IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Удалить из текста символ!
сообщение
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


Люди помогите плиз срочно. скоро сессия а немогу прогу сделать чтоб работала.
вообщем суть такова: надо считать файл, и если в нем попадается заданный символ, удалить его, но потом надо будет вернуть обратно. например, удалим пробелы из строки файла:

__ABC_____FDC__
чтобы допустим получилось
2,3ABC5,3FDC2,0

Получается что цифра перед запятой - это количество пробелов или последовательно идущих символа, а после запятой - через сколько символов опять будет пробел. Причем сделать мне это надо именно так (препод так сказал)

Язык программирования С++ Builder но тут вроде нету неизвестных функций
вот что получилось

void __fastcall TForm1::delClick(TObject *Sender)
{
char p[255];
sym=Edit->Text;
output=fopen ("WWW.txt","w");
u=0;
g=sym[1]; - это символ который надо удалить
i=0;
c=',';
while (!feof(input)) пока не конец файла
{
if (feof(input)) break;

fgets (p,255,input); считываем строку
for (i=1;i<strlen(p);i++) пока не конец строки
{
u=0; nu=0; u- количество подряд идущих пробелов например; nu-через сколько символов опять будет пробел
if (p[i]==g) {
k=i;
while (p[i]==g){ считаем кол-во повторов символа
u++;
i++;
}
while (p[i]!=g){ считаем через сколько опять пробел будет
i++;
nu++; }
s=IntToStr(u);
r=s[1];
fwrite (&r,sizeof(char),1,output);
fwrite (&c,sizeof(char),1,output);
s=IntToStr(nu);
r=s[1];
fwrite (&r,sizeof(char),1,output);}
else
{
while (p[k]==g)
k++;
fwrite (&p[k],sizeof(char),1,output);}

}

}
fclose (input);
fclose (output);
Mem->Clear();
output=fopen ("WWW.txt","r");
Mem->Lines->LoadFromFile("WWW.txt");
}


Сообщение отредактировано: Lapp -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


М
Почему в паскалевском разделе?.. Переношу в С.



--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






Child of Bodom, так что-ли:

#include <fstream.h>
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const int max_size = 256;
char buffer[max_size];

ifstream in_file("G:\\www.txt", ios::in);
ofstream out_file("G:\\www2.txt", ios::out);

char to_delete = ' ';
int count = 0;
while(!in_file.eof()) {
in_file.getline(buffer, max_size);

AnsiString result = "";
for(char *p = buffer; *p; p++) {
while(*p != to_delete) p++;

while(*p == to_delete) {
count += 1;
p++;
}
AnsiString after = "";
for(; *p && *p != to_delete; *p++) {
after += *p;
}
result +=
IntToStr(count) + "," + IntToStr(after.Length()) + after;
count = 1;
}
out_file << result.c_str() << endl;
}
out_file.close();
in_file.close();

Memo1->Lines->LoadFromFile("G:\\www2.txt");

}


?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


Цитата(volvo @ 18.12.2007 16:35) *

Child of Bodom, так что-ли:

#include <fstream.h>
...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const int max_size = 256;
char buffer[max_size];

ifstream in_file("G:\\www.txt", ios::in);
ofstream out_file("G:\\www2.txt", ios::out);

char to_delete = ' ';
int count = 0;
while(!in_file.eof()) {
in_file.getline(buffer, max_size);

AnsiString result = "";
for(char *p = buffer; *p; p++) {
while(*p != to_delete) p++;

while(*p == to_delete) {
count += 1;
p++; // вот тут че то не понятно
}
AnsiString after = "";
for(; *p && *p != to_delete; *p++) { // и вот это
after += *p;
}
result +=
IntToStr(count) + "," + IntToStr(after.Length()) + after;
count = 1;
}
out_file << result.c_str() << endl;
}
out_file.close();
in_file.close();

Memo1->Lines->LoadFromFile("G:\\www2.txt");

}


?




немного не понимаю в тех местах. Да и вроде все то, вроде так понятно. я так почти и делал(я эту лабу переделываю 10 раз наверно). Короче у меня часто возникает проблемы с этими char , *char, char [] вот и получается что допустим в новый файл с цифрами записывалось нормально(как то получилось один раз), но когда обратно восстанавливать по этим цифрам заданный символ наступают проблемы с этими чарами . Допустим я создал множество из цифр и типа считывается посимвольно и типа если входит в множество тогда их там преобразовываю считываю, но получается что никогда не совпадает, то есть никогда во множество то не входят цифры. Вот с этим в основном проблемы.
А это вообще C++ Builder 6 или 2007 ?

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Цитата
А это вообще C++ Builder 6 или 2007 ?

А тут не используется ничего такого, что изменилось бы, начиная с 6 версии. Я бы сказал, никаких специальных "примочек" Билдера тут вообще не используется. За исключением AnsiString и IntToStr все остальное - стандартные средства С++...

Теперь о том, что тебе не было понятно. Смотри:

// пробегаем по всей строке buffer, используя указатель на строку
for(char *p = buffer; *p; p++) {

// Сначала - пропускаем все символы, которые НЕ являются удаляемыми (т.е., пока
// очередной символ не является удаляемым, увеличиваем p, что означает переход
// к следующему символу строки buffer). По окончании этого цикла while переменная
// p будет указывать на первый удаляемый символ.
while(*p != to_delete) p++;

// Теперь надо посчитать, сколько удаляемых символов идут подряд
// Опять же увеличиваем указатель, пока текущий символ равен to_delete
// одновременно с этим, кстати, еще и увеличиваем счетчик (count)
while(*p == to_delete) {
count += 1;
p++; // что тут тебе было не понятно - я не знаю, это и есть переход на следующий символ строки
}

// В этой строке будут храниться все символы, следующие ПОСЛЕ удаляемых,
// для того чтобы вычислить расстояние до следующей группы пробелов (ну, или чего там у тебя)
AnsiString after = "";

// Здесь - использование преимуществ цикла for
// ОБЫЧНО в цикле for указываются начальные значения переменных ";" условие продолжения
// цикла ";" и оператор, выполняемый при переходе на следующую итерацию...
// У меня нет первого парамента, то есть, начальное значение p я не задаю, его значение останется
// таким же, каким и было при выходе из предыдущего цикла while...

// А вот продолжаться этот for будет, пока не будет достигнут конец строки
// (*p равносильно *p != 0, то есть, как только *p станет равным 0 - конец строки - цикл прервется)
// и очередной символ не будет являться пробелом (как только дойдем до следующего пробела -
// цикл тоже прервется)
for(; *p && *p != to_delete; *p++) {
// Что же делаем в цикле?
// Очень просто: добавляем очередной просмотренный символ в строку
after += *p;
}

// Ну, и собираем изо всех элементов результат, который нужен: счетчик пробелов, запятая,
// сколько символов будет до следующего пробела и сама строка до следующего пробела
result +=
IntToStr(count) + "," + IntToStr(after.Length()) + after;

// Не забываем сбросить счетчик, чтобы при следующем подсчете пробелов он считал правильно
count = 1;
}


А вообще-то тебе надо разобраться с указателями (это вообще рабочий инструмент в С++, без понимания, как они работают, тебе будет очень сложно что-то написать) и со строками.

Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


Цитата(volvo @ 18.12.2007 21:34) *


А вообще-то тебе надо разобраться с указателями (это вообще рабочий инструмент в С++, без понимания, как они работают, тебе будет очень сложно что-то написать) и со строками.


Круто. Вроде все теперь понял. Спасибо. Да на лекциях про указателя я наверно спал просто или в дурака играл. не помню.

Это седня попробую. А вот теперь при нажатии на вторую кнопку. надо все это вернуть из второго файла(т.е заданный символ в те места где он стоял) вот и там вот делать так чтоб допустим если цифра встречается сравнивать ее с множеством чисел если совпадает, то и т.д. .... Так наверно сделать??
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Гость






Восстановление исходной строки я бы делал так:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
const int max_size = 256;
char buffer[max_size];

int count = 0, after = 0;

ifstream infile("G:\\www2.txt", ios::in); // Это - "закодированный" файл
ofstream out_file("G:\\www3.txt", ios::out); // Сюда будет помещен результат...
char char_to_insert = ' ';

while(!infile.eof()) {
AnsiString result = "";
infile.getline(buffer, max_size);

char *p = buffer;
for(; *p; p++) {
if((sscanf(p, "%d,%d", &count, &after))) {
for(int i = 0; i < count; i++) {
result += char_to_insert;
}
p += (IntToStr(count) + "," + IntToStr(after)).Length() - 1;
}
else result += *p;
}
out_file << result.c_str() << endl;
}
out_file.close();
infile.close();

Memo1->Lines->LoadFromFile("G:\\www3.txt");
}

О том, что именно здесь делает sscanf - читай здесь, я уже объяснял как подобный фрагмент работает:
Задача по строкам
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


А вот еще у меня вопросик. Можно ли по этой технологии считывать не только текстовый файл но и .dat .dll ну или просто не только текстовый файл???
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






В принципе, если ты знаешь формат файла, который читаешь - то достаточно просто открыть файл как бинарный:
ifstream infile("myfile.dat", ios::in|ios::binary);
и работать с ним.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


void __fastcall TForm1::delClick(TObject *Sender)
{
const int max_size = 256;
char buffer[max_size];

input=fopen (vibor->FileName.c_str(),"r"); // тут из диалогового окна
output=fopen ("WWW.txt", "w");
sym=Edit->Text;
char to_delete = sym[1];
int count = 0;
while(!feof(input)) {
fgets (buffer,max_size,input);
AnsiString result = "";
for(char *p = buffer; *p; p++) {
while(*p != to_delete) p++;

while(*p == to_delete) {
count += 1;
p++;
}
AnsiString after = "";
for(; *p && *p != to_delete; *p++) {
after += *p;
}
result +=
IntToStr(count) + "," + IntToStr(after.Length()) + after;
count = 1;
}
out_file << result.c_str() << endl; // вот а как тут мне заменить тогда
}
fclose(input);
fclose(output);
Mem->Lines->LoadFromFile("WWW.txt");

}





А можешь сказать как там будет и ваще правильно ли будет так как я переделал, а то препод не поверит мне что я такой умный типа. Честно говоря мне си ваще не прет, вот паскаль это круто smile.gif) поэтому ваще вот помощи прошу

Сообщение отредактировано: Child of Bodom -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Вот так там будет:
void __fastcall TForm1::Button6Click(TObject *Sender)
{

const int max_size = 256;
char buffer[max_size];

if(!vibor->Execute()) return; // У тебя в коде не запускается OpenDialog

FILE *input = fopen (vibor->FileName.c_str(),"rt"); // Открываем ТЕКСТОВЫЙ файл = "rt"
FILE *output = fopen ("WWW.txt", "wt"); // и здесь тоже текстовый
AnsiString sym = Edit->Text;
char to_delete = sym[1];
int count = 0;
while(!feof(input)) {
buffer[0] = '\0'; // Буфер надо сбрасывать
fgets(buffer,max_size,input);
AnsiString result = "";
for(char *p = buffer; *p; p++) {
while(*p != to_delete) p++;

while(*p == to_delete) {
count += 1;
p++;
}
AnsiString after = "";
for(; *p && *p != to_delete; *p++) {
after += *p;
}
result +=
IntToStr(count) + "," + IntToStr(after.Length()) + after;
count = 1;
}
fprintf(output, "%s\n", result.c_str()); // Вывод в файл
}
fclose(input);
fclose(output);
Mem->Lines->LoadFromFile("WWW.txt");

}

P.S. Не имей привычки часто пользоваться глобальными переменными (или слишком много ненужного запихивать в класс) - это может тебе навредить...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


Так вывод я попробую по аналогии сделать. Спасибо большое за помощь, за советы.Попробую следовать им. Ща попробую все это скомпилить. Прикольно будет если получитсья
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


Слушай че то не то получается. Например, пишу удалить пробел а он еще часть текста удаляет:
Исходный файл:

Превед я тупой робот пните меня чтоб я начал работать

Полученный файл:

1,1я2,5робот2,4меня2,1я2,8работать
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






		for(char *p = buffer; *p; p++) {
// while(*p != to_delete) p++; // Эту строку можешь удалить...

while(*p == to_delete) {
count += 1;
p++;
}
У меня на твоем примере отработало...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


оооо круто работает!!!! Спасибо smile.gif))
ура ща буду смотреть кнопку возвращения обратно текста этого smile.gif)


Сообщение отредактировано: Child of Bodom -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


ой я скоро покончу с собой:(( препод начал проверять: открыл текстовый файл, одну строку нормально проработало. он говорит а че ты мне тока одну , давай я напишу текст и посмотрим как будет удаляться. ну вот он написал :

    на поле танки грохотали_                       //    _ это пробел поставил чтоб видно было
солдаты шли в последний бой_
а молодого китайца_
несли с пробитой головой_


Вот а после кодирования вот что получилось:

7,2на1,4поле1,5танки1,9грохотали1,1
1,2х1,3Х‰1,3Х‰1,3¤G’1,1„
4,7солдаты1,3шли1,1в1,9последний3,3бой1,1

3,1а1,8молодого1,7китайца1,1
1,3ний3,3бой1,1

7,5несли1,1с1,8пробитой1,7головой


я понимаю что уже достал вас но мне ее надо последний срок в понедельник, а я ваще не чаю что уж теперь сделать. Помогите прошу!!!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






А теперь расскажи, что ИМЕННО ты вводишь? У тебя в конце каждой строки что расположено? Перевод строки? Что же ты хотел? Я тебе для чего в самом начале говорил делать это через поток ifstream + метод getline? Потому что этот метод читает всю строку, не включая символ перевода строки. Ты переделал по-своему, теперь ищи в buffer-е после прочтения символ '\n' и выкидывай его из буфера (т.е., заменяй символом '\0'). Тогда получишь в результате обработки файла

    na pole tanki grohotali_
soldaty shli v posledniy boy_
a molodogo komandira_
nesli s probitoi golovoy_
вот такой результат в Memo:
4,2na1,4pole1,5tanki1,9grohotali
4,7soldaty1,4shli1,1v1,9posledniy3,3boy
3,1a1,8molodogo1,9komandira
7,5nesli1,1s1,8probitoi1,7golovoy
(пробелы в конце строки будут тоже выброшены из рассмотрения, при обратной конвертации надо будет добавить в конец строки еще один пробел) или переписывай алгоритм с нуля... Я больше с FILE* (при использовании C++ Builder-а) извращаться не буду. В С++ есть гораздо более подходящие для этого средства...


Добавлено через 19 мин.
Хотя, если я правильно понимаю, что именно должно получиться, попробуй вот это:
void __fastcall TForm1::Button6Click(TObject *Sender)
{
const int max_size = 256;
char buffer[max_size];

if(!vibor->Execute()) return;
FILE *input = fopen (vibor->FileName.c_str(),"rt");
FILE *output = fopen ("G:\\WWW4.txt", "wt");
AnsiString sym = Edit->Text;
char to_delete = sym[1];
int count;
while(!feof(input)) {
buffer[0] = '\0';
fgets(buffer,max_size,input);

AnsiString result = "";
for(char *p = buffer; (*p) && (*p != '\n'); p++) {
count = 0;

while(*p == to_delete) {
count += 1;
p++;
}
AnsiString after = "";
for(; *p && *p != '\n' && *p != to_delete; *p++) {
after += *p;
}
p -= 1;
result +=
IntToStr(count) + "," + IntToStr(after.Length()) + after;
}
fprintf(output, "%s\n", result.c_str());
}
fclose(input);
fclose(output);
Mem->Lines->LoadFromFile("G:\\WWW4.txt");

}

 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Новичок
*

Группа: Пользователи
Сообщений: 45
Пол: Мужской

Репутация: -  0  +


Спасибо большое еще раз. Вроде пашет.ну при определенных параметрах. может прокатит
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 8.12.2021 17:06
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name