спецы по с/с++ помогите чайнику.. -)

Sw_Lem
Уже с Приветом
Posts: 1093
Joined: 26 Jul 2001 09:01
Location: WI

спецы по с/с++ помогите чайнику.. -)

Post by Sw_Lem »

Помогите плиз написать программу которая, допустим, натравливается на файл text.txt и заменяет все встретившиеся ей по пути цифры на те же цифры в кавычках?
напр. x1c17 --> x(1)c(17)

Или подскажите софт который умеет такое делать, но не пошагово, заменяя по одному типу символов за один проход, а сразу несколько. (допустим эти цифры у меня в тексте будут по величине до 100 или еще больше, ведь запаришься вручную по 100 проходов запускать)...

Спасибо большое..
я пришел к тебе с приветом..
Sudakovich
Новичок
Posts: 89
Joined: 14 Dec 2003 16:32
Location: Одесса->Encino, CA

Post by Sudakovich »

Что ж помочь, помогаю:
1. Как вы там сказали натравливаем - это может быть чем угодно от обыкновенного от fscanf до fstream и OpenFile все зависит в чем вы собираетесь компилить и вообще какой у вас С++
2. Дальше все как обычно проходитесь по файлу по символьно и проверяете
с помощью функции isdigit не является ли это(текущий символ) цифрой, как только нашли, поставили перед символом скобку, далее, в цикле опять же, проверяете той же функцией только на !isdigit - то есть на что-то отличное от цыфры, нашли - поставили скобку и так далее.
3. Конечно можно накрутить там всяких проверок и туда сюда, но это самое простое решение как говорится дешево и со вкусом, за 10 минут усиленного программирования справитесь(вместе с тестированием)

Теперь на счет второй части вашего письма:
Я не думаю что такой софт вы найдете, разьве что на referats.ru - курсовая работа для экономистов заочников, и то там будет заменить не на скобку а на символи @ - оно вам надо, лучше создать свой шедевр.

Далее вопрос такой что значит сразу несколько, вы же знать должны в какой у вас позиции начало цифр а в какой конец, нет я конечно не спорю можно создать спец таблицу, в которой все расписано начало конец куда поставить, но не кажется ли вам это уж сильно через чур, все таки не пентагон ломаем(тем более что все равно придется просмотреть файл пошагово, чтобы эту карту создать).

Про то что что в скобке я вообще ничего не понял, цифры по величине или по значению и что вы там собрались запариватся, чай не в вручную делать будете, конечно если у вас не калькулятор. Даже 286 с 4 метрами оперативки очень прилично с такой задачей справится, правда если файл сильно большой, то предктся подождать, ну ничего потерпим, все равно быстрее чем в ручную :wink:

Кстате, а что вы вручную хотели запускать??
НУ коль не справитесь с такой задачей, милости просим, всем форумом поможем и напишем, а если не всем, то хотябы половиной
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

awk grep vi sed
Верить нельзя никому - даже себе. Мне - можно!
Sw_Lem
Уже с Приветом
Posts: 1093
Joined: 26 Jul 2001 09:01
Location: WI

Post by Sw_Lem »

A. Fig Lee wrote:awk grep vi sed


что из них поддерживает списки замен?
я пришел к тебе с приветом..
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Sw_Lem wrote:
A. Fig Lee wrote:awk grep vi sed


что из них поддерживает списки замен?

реплейсать можно с awk vi sed
Верить нельзя никому - даже себе. Мне - можно!
111001
Posts: 11
Joined: 04 Apr 2004 01:40

Re: спецы по с/с++ помогите чайнику.. -)

Post by 111001 »

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAXLINELENGTH 3000

static const char * replace( char *s)
{
  static char res[ 3*MAXLINELENGTH + 10];
  char *to = res;
  for( ; *s ; s++)
  {
    if( isdigit(*s) )
    {
      *to++ = '(';
      *to++ = *s;
      while( isdigit(s[1]) )
        *to++ = *++s;
      *to++ = ')';
    }
    else
      *to++ = *s;
  }
  *to = '\0';
  return res;
}

int main(int na, char **aa)
{                                 
  const char  * fnm;
  const char  * tmp = "temporary$$$file.txt";
  FILE        * f, *w;
  char          buf[MAXLINELENGTH+10] = {0};

  if( na < 2 )
  {
    printf("\nexpected parameter - filename\n");
    return -1;
  }

  fnm = aa[1];
  f = fopen(fnm,"r");

  if(!f)
  {
    printf("\nCannot open %s\n", fnm );
    return -1;
  }

  w = fopen(tmp,"w");

  for(;;)
  {
    if( feof(f) || ! fgets(buf, MAXLINELENGTH, f) )
      break;
    fprintf(w, "%s", replace(buf) );
  }
  fclose(w);
  fclose(f);

  unlink( fnm );
  rename( tmp, fnm );

  return 0;
}
Last edited by 111001 on 12 Apr 2004 10:51, edited 1 time in total.
User avatar
theukrainian
Уже с Приветом
Posts: 2506
Joined: 13 Jan 2003 22:34
Location: Kiev :: Los Angeles, CA

Re: спецы по с/с++ помогите чайнику.. -)

Post by theukrainian »

Sw_Lem wrote:Или подскажите софт который умеет такое делать, но не пошагово, заменяя по одному типу символов за один проход, а сразу несколько. (допустим эти цифры у меня в тексте будут по величине до 100 или еще больше, ведь запаришься вручную по 100 проходов запускать)

Для максимальной пользы, все-таки советую писать самому - чай на работе за вас писать не будут. А если будут, то будут долго и мерзко матюкаться :) Если хотите научиться - пишите самостоятельно, а потом пишите сюда (а еще лучше в comp.lang.c) - вас поправят. Так и научитесь.

Вам даже алгоритм Sudakovich уже написал. Заметьте, отличается от преведенного выше примера, и мне кажется намного проще. И решает вашу проблему со 100-значными цифрами, если я ее правильно понял
Last edited by theukrainian on 12 Apr 2004 05:22, edited 1 time in total.
User avatar
theukrainian
Уже с Приветом
Posts: 2506
Joined: 13 Jan 2003 22:34
Location: Kiev :: Los Angeles, CA

Re: спецы по с/с++ помогите чайнику.. -)

Post by theukrainian »

111001 wrote:...

По-моему не работает когда число приходится на границу строки в которой вы делаете replace.

также, по-моему unlink это не ANSI функция. Может POSIX, но я не уверен. Существует remove(), который и стоит использовать.

feof() по-моему не нужен. Он нужен если вы хотите отличить конец файла от ошибки. Если же просто проверять закончили мы читать или нет, можно этого не делать

а файл я бы открывал в binary - если честно то text streams я даже никогда по-моему и не использовал, но сдается мне что там могут быть заморочки с tabs и другими non-printable characters.

пс. возвращать из main (как учит ANSI), стоит EXIT_SUCCESS или EXIT_FAILURE.
User avatar
Оранжевое Небо
Уже с Приветом
Posts: 723
Joined: 17 Sep 2003 10:00

Post by Оранжевое Небо »

Возможно поможет regex из boost.org
Смотри, не обломись на полдороги - товарищ "Небо"
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

читать символы и реплейсать лучше поштучно - меизвестно какой длины строки.
Все равно awk лучше - раз вючишь, не придется потом 2-ю программу писать.
Верить нельзя никому - даже себе. Мне - можно!
Hatih
Уже с Приветом
Posts: 750
Joined: 10 Dec 2003 20:11

Post by Hatih »

Code: Select all

perl -pe 's/(\d+)/"$1"/g' text.txt
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

Hatih wrote:

Code: Select all

perl -pe 's/(\d+)/"$1"/g' text.txt

"ты знал, ты знал!"
точна, про Perl, великий и могучий я совсем забыл. С php тоже можно.
Верить нельзя никому - даже себе. Мне - можно!
111001
Posts: 11
Joined: 04 Apr 2004 01:40

Post by 111001 »

Hatih wrote:

Code: Select all

perl -pe 's/(\d+)/"$1"/g' text.txt


Code: Select all

perl -i -pe 's/\d+/($&)/g' test.txt


Windoz:

Code: Select all

perl -i'.bak' -pe "s/\d+/($&)/g" text.txt
111001
Posts: 11
Joined: 04 Apr 2004 01:40

Re: спецы по с/с++ помогите чайнику.. -)

Post by 111001 »

theukrainian wrote:По-моему не работает когда число приходится на границу строки в которой вы делаете replace.

Would you provide an example, please?
User avatar
theukrainian
Уже с Приветом
Posts: 2506
Joined: 13 Jan 2003 22:34
Location: Kiev :: Los Angeles, CA

Re: спецы по с/с++ помогите чайнику.. -)

Post by theukrainian »

111001 wrote:
theukrainian wrote:По-моему не работает когда число приходится на границу строки в которой вы делаете replace.

Would you provide an example, please?

i could be wrong... but i think situation like the following:
"abcd.......123456abcd", where, say, '3' is symbol number MAXLINELENGTH (ie, if MAXLINELENGTH is 1000, then '3' is symbol number 1000, since fgets() will read at most MAXLINELENGTH - 1 (and null-terminate)...or stop at '\n' if it sees one).

There reason it seems to me that it does not work is because replace function is going to be called on "abcd....12", resulting in output of "abce...(12", and then it'll be called again on "3456.... " resulting in output of "(3456).....".

To fix this, replace() would need to keep state between invocations, but this would not be pretty.

I could be off by one, but what matters is the idea itself :)

.. am I missing something?
111001
Posts: 11
Joined: 04 Apr 2004 01:40

Re: спецы по с/с++ помогите чайнику.. -)

Post by 111001 »

theukrainian wrote:
111001 wrote:
theukrainian wrote:По-моему не работает когда число приходится на границу строки в которой вы делаете replace.

Would you provide an example, please?

i could be wrong... but i think situation like the following:
"abcd.......123456abcd", where, say, '3' is symbol number MAXLINELENGTH (ie, if MAXLINELENGTH is 1000, then '3' is symbol number 1000, since fgets() will read at most MAXLINELENGTH - 1 (and null-terminate)...or stop at '\n' if it sees one).

There reason it seems to me that it does not work is because replace function is going to be called on "abcd....12", resulting in output of "abce...(12", and then it'll be called again on "3456.... " resulting in output of "(3456).....".

To fix this, replace() would need to keep state between invocations, but this would not be pretty.

I could be off by one, but what matters is the idea itself :)

.. am I missing something?


Спасибо за ответ.
Я, конечно, предполагал, что MAXLINELENGTH выбрана
достаточно большой, так что любая строка заведомо короче. Иначе все это лучше делать на бинарном потоке,
не разбивая на строки.
ig
Уже с Приветом
Posts: 491
Joined: 09 Apr 2000 09:01
Location: Tigard, OR

Post by ig »

Sw_Lem,

тут уже рекомендовали perl, вот с таким шаблоном должно работать:

<pre>s/([^(\d]|^)(\d+)(?![)\d])/$1($2)/g</pre>

Return to “Вопросы и новости IT”