Перейти к содержимому

Фото
- - - - -

Помогите пожалуйста с С++


  • Вы не можете создать новую тему
  • Please log in to reply
29 ответов в этой теме

#1 Native

Native
  • Новобранец
  • 1 сообщений

Отправлено 01 апреля 2005 - 10:23

Всем привет.

Помогите пож. разобраться как можно удалить строчку из
текстового файла. Где ни смотрел, везде десяток функций на запись в файл, создание, управление потоками, но ни одной на удаление из файла.
  • 0

#2 Syd[eX]

Syd[eX]
  • Пользователь
  • 57 сообщений
  • Откуда:Таллинн

Отправлено 01 апреля 2005 - 11:50

и не нужна такая функция - считываешь файл в буфер, в буфере удаляешь строку и пишешь буфер по новой в файл.
  • 0
Кто еб*тся в дождь и грязь?
Наша доблестная связь.

#3 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 01 апреля 2005 - 13:10

:D типично сишный подход... как же я вас сишников не люблю с ТАКИМИ решениями...
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#4 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 01 апреля 2005 - 15:03

a s KAKIMI ty ljubish? tam gde vse za tja delaet odna funcija? tak blin eta funkcija skoree vsego tak i realizovana, kak ty skazal, po-cishnomu.
  • 0
int main(void)

#5 Syd[eX]

Syd[eX]
  • Пользователь
  • 57 сообщений
  • Откуда:Таллинн

Отправлено 01 апреля 2005 - 15:09

a s KAKIMI ty ljubish? tam gde vse za tja delaet odna funcija? tak blin eta funkcija skoree vsego tak i realizovana, kak ty skazal, po-cishnomu.

Просмотреть сообщение


- наш человек :)))

В си тоже можно придумать решение с побитным считывание файла с диска - поиском всякой лажи в нём - а какой смысл ? Не жрать память ? Ой Зайка, прости за грубость! больше сожрёшь пока эту лажу реализуешь чем то если сделать нормально по человечески (оно же - по Сишному) :)))
  • 0
Кто еб*тся в дождь и грязь?
Наша доблестная связь.

#6 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 01 апреля 2005 - 15:22

ves' file v buffer neobjazatel'no schityvat' tozhe, dostatochno buffera dlja stroki, dal'she delat' sravnenie, naprimer:
/* read_line.c */
#include <stdio.h>
#include <string.h>

int
main(void)
{
  char buf[0x80];
  char *line = " char *line";
  FILE *fp;

  fp = fopen("read_line.c", "r");
  if (!fp)
  {
    perror("fopen");
    return 1;
  }

  while (fgets(buf, sizeof buf, fp))
  {
    if (strncmp(line, buf, strlen(line)))
      printf("%s", buf);
  }
      

  fclose(fp);
  return 0;
}



Сообщение изменено: V^v (01 апреля 2005 - 15:23 )

  • 0
int main(void)

#7 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 01 апреля 2005 - 18:49

А по какому критерию строка удаляется?
Лично мне тоже кажется, что проще удалять строку при считывании, но это зависит от критерия удаления (если он основан на сравнении с другими строками, то дело несколько сложнее).


V^v, запутаешь человека, твоя програмка на C, а не на C++ (хотя компилятор C++ ее проглотит, скорее всего, обратная совместимость).

Или на C тоже можно? В конце концов языки родственные и во многом похожи.



:D типично сишный подход... как же я вас сишников не люблю с ТАКИМИ решениями...

Просмотреть сообщение

Zero, приведи пример неТАКОГО решения. Обсудим, почему тот или иной подход лучше или хуже.
Только не надо беспочвенно опускать язык программирования только потому, что он тебе не нравится (или не хватило терпения его освоить в достаточной мере, что скорее всего).

Ждем примера с несишным подходом, мне жутко интересно стало..
  • 0

#8 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 01 апреля 2005 - 21:26

V^v, запутаешь человека, твоя програмка на C, а не на C++ (хотя компилятор C++ ее проглотит, скорее всего, обратная совместимость).

da, konechno, moj primer na C.
  • 0
int main(void)

#9 Syd[eX]

Syd[eX]
  • Пользователь
  • 57 сообщений
  • Откуда:Таллинн

Отправлено 02 апреля 2005 - 00:37

Не по топику:

На самом деле, си и си++ не просто родственные языки - си++ как мы все знаем наследующий си язык. Просто использующий ООП (что кстати говоря последнее время становится достаточно спорной темой, некоторые уже несколько лет говорят что технология провальная, в основном так выражаются достаточно уважаемая профессура - математики, фанаты lisp - кстати я придерживаюсь той же позиции - ООП слишком громоздкая система, почти всё вполне реально решается функциями и базовыми классами, без методов, евентов и прочей не нужной билеберды, зачем это всё при решении простых задач ?)

пару ссылочек по теме, очень интересные статьи - я долго и с интересом читал - и извлёк из этого то, что не один я такой (думал до этого что дурак и не понимаю всей идеи ООП по причине своей безграмотности):
http://bugtraq.ru/li...optheology.html
предистория предидущей статьи:
http://bugtraq.ru/li...havefailed.html
http://bugtraq.ru/li...enotfailed.html

По теме:

Так, что я думаю проблемы нету - к тому же на Си такие приложения удобнее писать - использование ООП не имеет смысла в данном случае. И сиплюсовские навороты вроде, писания в поток не имеют смысла в данном случае, я думаю.

Думаю можно и так написать (по сути тоже самое только другими словами):

#include <stdio.h>
#include <string.h>
#define __MBUFS 256
#define __FILE "test.txt"
#define __SSTR "the quick brown fox jumped over a lazy dog"

int main(void) {
char buf[__MBUFS];
for(int i=0;i<=__MBUFS;i++) buf[i]=NULL; // не факт что буфер пустой при создании - некоторые компиляторы и некоторые платформы заполняют билебердой - например Borland Builder - стоит очистить иначе проблемы возникают
FILE * r_handle = fopen(__FILE, "r");
FILE * w_handle = fopen(__FILE, "w"); // покуда пишет из буфера только по закрытию файла насколько я помню будем читать и писать одновременно
while(fgets(buf, __MBUFS, r_handle))
if(!strcmp(buf, __SSTR, sizeof(buf) fprintf(w_handle, "%s", buf);
fclose(r_handle);
fclose(w_handle);
}

просто немножко покороче - а вообщем то тоже самое.
Других вариантов так сходу и не придумать но уверен что если подумать можно что нибудь и придумать. На самом деле здорово бы увидеть другое решение - присоединяюсь к Sergio - с удовольствием бы посмотрел какое нибудь нестандартное решение. Авось кто нибудь покажет ?

Сообщение изменено: Syd[eX] (02 апреля 2005 - 00:47 )

  • 0
Кто еб*тся в дождь и грязь?
Наша доблестная связь.

#10 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 00:54

a s KAKIMI ty ljubish? tam gde vse za tja delaet odna funcija? tak blin eta funkcija skoree vsego tak i realizovana, kak ty skazal, po-cishnomu

Нет, я не терплю подход с чтением гигабайтного файла в буфер...
Функция говоришь? Да нет, я б сам ее писал...

В си тоже можно придумать решение с побитным считывание файла с диска - поиском всякой лажи в нём - а какой смысл ? Не жрать память ? Ой Зайка, прости за грубость! больше сожрёшь пока эту лажу реализуешь чем то если сделать нормально по человечески (оно же - по Сишному

Побитно ты нигде считать не сможешь. Контроллер диска физически может выдать сектор не меньше. Правда если запрограммировать ДМА, то можно и 1 байт считать, но побитно нет.
Если тебе не дорога память, нам с тобой не о чем говорить.
Как я сожру память пока реализую?(что, с каждой компиляцией у меня ее будет все меньше? :-D ) У меня был бы буфер байт в 100. А у тебя размером с файл. Если нет столько оперативки, будешь через своп гонять с диска на диск. Смысл?
Сишники...
Не о чем нам с вами говорить, ребята.

Добавлено в [mergetime]1112395945[/mergetime]
Sergio, да нет. Дело не в том что не освоил... Долгая история. У всех свои языки. У меня - принципиально другие.
Я б считывал построчно с небольшим буфером.

Добавлено в [mergetime]1112396024[/mergetime]
А про сишный подход - не обижайтесь, плиз. Просто чаще мне попадались на жизненном пути горе-программисты именно на си. привычка. Не обижайтесь.

Добавлено в [mergetime]1112396087[/mergetime]
V^v, это я и имел ввиду.

Сообщение изменено: Zero (02 апреля 2005 - 00:55 )

  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#11 Syd[eX]

Syd[eX]
  • Пользователь
  • 57 сообщений
  • Откуда:Таллинн

Отправлено 02 апреля 2005 - 00:55

Зеро подобный пример тебе привели.
Проблема в том что, насколько я прав, если не прав поправьте пожалуйста, функция считывания в буфер и записи из него запишет данные в файл - тогда, и только тогда когда ты закроешь хендлер.
Поэтому это так и не изменить.
Конечно вариант - переписать функцию.
С битами пардон погорячился - я к слову вообщем то привёл.
Можешь показать как бы ты решил - язык на твой выбор.
Просто интересно посмотреть другое решение, чем были приведены выше.
  • 0
Кто еб*тся в дождь и грязь?
Наша доблестная связь.

#12 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 01:03

и не нужна такая функция - считываешь файл в буфер, в буфере удаляешь строку и пишешь буфер по новой в файл.

Вот ТВОИ слва. Т.е. ты предлагаешь считать ВЕСЬ файл в буфер а потом записать. Я просто гипотетически в таких ситуациях рассчитываю на 1 Гбт файл :-)
Я же предложил считать н-1 строку, потом 1 пропустить и идти дальше.
Про запись в файл - ты не прав.
По крайней мере при моем методе решения каждая строка сразу пишется в файл. По close пишется размер.
Могу привести пример на Фортране.

Добавлено в [mergetime]1112396582[/mergetime]
Можно еще найти смещение и размер строки, тогда работать с файлом как с двоичным НАМНОГО быстрее будет - поверьте моем у опыту.
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#13 Syd[eX]

Syd[eX]
  • Пользователь
  • 57 сообщений
  • Откуда:Таллинн

Отправлено 02 апреля 2005 - 01:06

Зеро,
пардон :lol: только сейчас заметил какую глупость слепил изначально. Немножко не это имел ввиду, сорри.

Хмммм, насчёт считывания строки в буфер - вообщем то пример то обычные решение обычное.
Всё равно придётся считывать весь файл так или иначе - то бишь прошерстить все строчки. Я вот о чём задумался - интересно а реально придумать алгоритм при котором не надо шерстить всё... вообще чисто гипотетически
  • 0
Кто еб*тся в дождь и грязь?
Наша доблестная связь.

#14 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 01:11

Гипотетически реально. Давай договоримся, по какому признаку удалять строку.
Шерстить придется так и так(если б это была БД индексированная ... :-) )
Но считывание строк очень медленно. Есть смысл после выкидывания строки с файлом работать как с двоичным.
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#15 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 02 апреля 2005 - 02:31

Нет, я не терплю подход с чтением гигабайтного файла в буфер...

Про гигабайты речи нигде не было.

У меня был бы буфер байт в 100.

А если в строке 250 символов?
На длину строки ведь тоже, как и на размер файла, ограничений пока не было наложено

Я б считывал построчно с небольшим буфером.

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

Так, что я думаю проблемы нету - к тому же на Си такие приложения удобнее писать - использование ООП не имеет смысла в данном случае. И сиплюсовские навороты вроде, писания в поток не имеют смысла в данном случае, я думаю

Согласен. Я и не говорил, что есть проблема. Отличаются языки С и C++ не только ООП. В C++, в отличие, например, от явы, ООП не является обязательным. Это подразумевает, что программист может сам выбирать, когда использовании ООП оправдано, а когда проще обойтись без него. Если бы технология была провальной, C++ не был бы самым популярным языком программирования уже более 10 лет (сколько точно, не знаю). И это несмотря на наличие целой кучи альтернатив, которые "лишены недостатков C++", perl, python, tcl/tk, ruby, scheme.. Тот же лисп. И пока не видно подходящей замены.

Правда, остальные отличия (между си и си++) скорее формальные, чем принципиальные, но все же они есть. И в названии темы фигурирует именно C++. Но лично мне без разницы, си так си.

Отошли немного от темы.
  • 0

#16 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 14:28

Я сказал байт в 100 а не в 100 байт. Т.е. примерно.

Про гигабайты речи нигде не было.

Было. Я уже показал вверху, что кто-то собирался весь файл читать в буфер, а ограничений на его размер не было.


Добавлено в [mergetime]1112444613[/mergetime]
Си в 70х придумали.

Добавлено в [mergetime]1112444922[/mergetime]

На мой взгляд, самый очевидный подход, независимо от языка программирования.

Ну вот именно! А зачем весь-то файл в буфер читать?
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#17 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 02 апреля 2005 - 16:09

Си в 70х придумали.

eto tak. chto ty hotel etim skazat'?

ne nado zabyvat' eshe odno: i stroka tozhe mozhet byt' razmerom v gigabajt, poetomu mozhno napisat' takuju funkciju, kotoraja schityvaet stroki proizvol'noj dliny:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF 4096

char *mygetline(FILE *fp);

/* lng_line.c */
int
main(void)
{
  FILE *fp;
  char *str = NULL;

  if ((fp = fopen("long.txt", "r")) == NULL)
  {
    perror("fopen");
    return EXIT_FAILURE;
  }

  str = mygetline(fp);
  if (str != NULL)
    printf("%d\n", strlen(str));

  free(str);
  return 0;
}

char *mygetline(FILE *fp)
{
  size_t len = 0;
  size_t buffer = BUF;
  int c;
  char *p = malloc(BUF + 1);

  if (!p)
    return NULL;

  while ((c = fgetc(fp)) != '\n' && (c != '\0'))
  {
    if (len >= buffer)
    {
      char *sav = p;
      sav = realloc(p, len + BUF + 1);
      if (sav != NULL)
      {
        p = sav;
        buffer += BUF; /* novaja max dlina bufera */
      }
      else /* Oshibka pri remalloc() */
      {
        free(p); /* pamjat' pod p osvobozhdaetsja */
        return NULL;
      }
    }
    p[len++] = c;
  }

  p[len] = c; /* '\n' ili '\0' */

  return p;
}


  • 0
int main(void)

#18 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 18:51

Конечно, может быть и строка в гиг, но тогда надо просто увеличить буфер, а без надобности это делать - память съедать...
Все же более вероятно, что размер файла будет велик, а размер строк - не очень. Обычно так и бывает...
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#19 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 02 апреля 2005 - 19:08

obychno byvaet vse chto ugodno.

но тогда надо просто увеличить буфер

moja funkcija eto i delaet

а без надобности это делать

delaet s nadobnostju. esli ty imeesh v vidu to, chto kogda stroka skazhem 4100 simvolov, (to est' na 4 bol'she chem bufer v moej proge), togda 4092 bajta svobodnye, ne takaja uzh velikaja trata pamjati, po krajenj mere tak proishodit vezde, gde pamjat' vydeljaetsja dinamicheski blokami.
  • 0
int main(void)

#20 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 20:16

Я про твой вариант решения ничего не говорю. Твой мне нравится.
Я возмущался по поводу предложеного в первую очередь чтения всего файла в буфер.
Понимаете, допустим, текстовый файл - документация(напрмиер). Размер - 100 Мбт. Его посторочно можно и на 4 Мбт памяти перекидать. А если целиком читать, то тут уж зависит от О/С - есть ли там свопинг и т.д., что за платформа... А /твой/ вариант меня устраивает...
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#21 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 02 апреля 2005 - 20:33

ves' file eto, konechno, ne goditsja, to est' byvaet inogda nado, no ne v dannom sluchae. Ja dumaju chelovek predlozhil eto prosto v kachestve varianta, ne obdumyvaja detali, prosto kak algoritm.
  • 0
int main(void)

#22 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 02 апреля 2005 - 21:39

Потому я и рассердился, что в первую очередь предложили этот алгоритм...
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#23 Sergio

Sergio
  • Постоялец
  • 3 051 сообщений

Отправлено 03 апреля 2005 - 01:39

Я возмущался по поводу предложеного в первую очередь чтения всего файла в буфер.

Оправдано, если на размер исходного файла наложено ограничение. Такое тоже бывает, и не так уж редко.

Достаточно вспомнить Notepad от Microsoft'а. В win9x эта прога не открывала файлы больше 64 КБ. Другой прикол состоял в том, что если размер какого-то файла конфигурации (сейчас не помню, system.cfg что ли, или как то так) превышал 64 КБ, то система вешалась при загрузке. Так что есть с кого брать пример:) Хотя думаю, в NT и XP это исправлено.

А если серьезно, то в большинстве случаев, конечно, лучше, когда буфер небольшой. Универсальнее.
  • 0

#24 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 03 апреля 2005 - 02:05

В постановке задачи не было ограничени. Я как робот - ограничений не было, значит...

А если серьезно, то в большинстве случаев, конечно, лучше, когда буфер небольшой. Универсальнее.

Just my thought!
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#25 tomatensaft

tomatensaft

    Samurai Jack

  • Пользователь
  • 449 сообщений
  • Откуда:Tallinn

Отправлено 04 апреля 2005 - 21:11

Вау, какие я тут темы пропускаю... 8-) Интересное чтение -- особенно дебаты на тему "кто был прав"... =)
  • 0
"This is all I want'd t' say 'bout dat..." © Forest Gump

#26 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 06 апреля 2005 - 11:55

Вау, какие я тут темы пропускаю... 8-) Интересное чтение -- особенно дебаты на тему "кто был прав"... =)

Просмотреть сообщение

aga, eshe kak interesno.
kstati, davno tebja zdes' ne bylo vidno, s vozvrasheniem :D
  • 0
int main(void)

#27 libricon

libricon
  • Постоялец
  • 572 сообщений
  • Откуда:Маарду

Отправлено 06 апреля 2005 - 14:35

так кто же прав , слежу за темой с момента создания
  • 0
Пингвин птица гордая, пока не пнешь, не полетит!!!

#28 tomatensaft

tomatensaft

    Samurai Jack

  • Пользователь
  • 449 сообщений
  • Откуда:Tallinn

Отправлено 06 апреля 2005 - 18:33

Трудно сказать... Думаю, это был коллективный труд. =) Если позволите, резюме:

1) ни в Стандартной библиотеке С++, ни С такой функции нет, и не нужно
2) при необходимости (если такой алгоритм может выполняться несколько раз в приложении), такую процедуру можно реализовать самостоятельно
3) реализация этой процедуры может быть осуществлена с помощью чистого С, без применения средств С++, хотя и средства С++ могут помочь
4) в зависимости от налагаемых на реализацию ограничений, процедура может быть реализована по-разному: от простейшего чтения всего файла в буфер до чтения файла в двоичном режиме в небольшой буфер с сравнением с искомой строкой посимвольно.
5) примеры были предоставлены обозрению широкой публики =)

Сообщение изменено: tomatensaft (06 апреля 2005 - 18:37 )

  • 0
"This is all I want'd t' say 'bout dat..." © Forest Gump

#29 Zero

Zero

    TRUST NO ONE

  • Постоялец
  • 10 668 сообщений
  • Откуда:Таллин

Отправлено 06 апреля 2005 - 19:51

Прально. Совершенно пралллльно...
  • 0
Моя Родина - СССР! Пролетарии всех стран, соединяйтесь!
-----------------------------------------------------------------------
Ясность - одна из форм полного тумана. Форумчане, давайте жить дружно!

#30 libricon

libricon
  • Постоялец
  • 572 сообщений
  • Откуда:Маарду

Отправлено 06 апреля 2005 - 20:53

метко!
  • 0
Пингвин птица гордая, пока не пнешь, не полетит!!!