Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

С: подкорректировать работу со строками

53K
30 января 2010 года
Iworb
17 / / 30.01.2010
Написал программу, которая ищет во всех строках предлоги и заменяет их на восклицательные знаки по количеству символов. Но вот незадача - функцию поиска-замены я брал не свою (брал отсюда), поэтому и возникли проблемы:
например есть слово "проводник" и предлог "од", так вот он слово "проводник" преобразует в "пров!!ник". Нужно реализовать поиск предлогов, учитывая, что после них должен идти разделитель. Массив разделителей указан, но как реализовать - ума не приложу.

среда Turbo c++
Написать надо на С
код программы:
Код:
#include<errno.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ST 10

char* modString(char *string, char *strReplaced, char *strReplacedBy)
{
    int originalStringLength, strReplacedLength, strReplacedByLength;
    int posReplacingCount, posReplacingNumber;
    int i, j, k;
    int *numpos;
    char *result;
    originalStringLength = strlen(string);
    strReplacedLength = strlen(strReplaced);
    strReplacedByLength = strlen(strReplacedBy);
    posReplacingCount = 0;
    numpos = (int*)malloc(sizeof(int) * (originalStringLength / strReplacedLength + 1));
    for(i = 0; i <= originalStringLength - strReplacedLength; ++i)
    {
        j = 0;
        while(j < strReplacedLength && string[i + j] == strReplaced[j])
            ++j;
        if(j == strReplacedLength)
        {
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }
    }
    if(!posReplacingCount)
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + 1));
        strcpy(result, string);
    }
    else
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + (strReplacedByLength - strReplacedLength) * posReplacingCount + 1));
        for(i = 0, j = 0, posReplacingNumber = 0; i < originalStringLength; ++i, ++j)
            if(posReplacingNumber == posReplacingCount || numpos[posReplacingNumber] > i)
                result[j] = string;
            else
            {
                for(k = 0; k < strReplacedByLength; ++k, ++j)
                    result[j] = strReplacedBy[k];
                i+= strReplacedLength - 1;
                --j;
                ++posReplacingNumber;
            }
        for( ; i < originalStringLength; ++i, ++j)
        result[j] = string;
        result[j] = '\0';
    }
    free(numpos);
    return result;
}

void main()
{
    FILE *f;
    char *fli[ST], *pch, *ptr;
    char ch, *p;
    char predl[13][7]={"v","k","s","a","do","po","iz","na","od","bez","pri","pered","cherez"},
         zamen[13][7]={"!","!","!","!","!!","!!","!!","!!","!!","!!!","!!!","!!!!!","!!!!!!"},
         razdel[9][1]={",","."," ","\0","!","?","(",")","\""};
    int i, col_st=0, j, k;
    clrscr();
    printf("vyberite metod vvoda:\n1 - s klaviatury\n2 - s faila temp.txt\n");
    ch=getch();
    if(ch==49)
    {
        printf("\nVvod s klaviatury\n");
        printf("\nSkoka budet strok:");
        scanf("%d", &col_st);
        if((col_st<1)||(col_st>ST))
        {
            printf("error! Dolzhno byt` ne men`she 1 i ne bol`she 10 strok!");
            exit(-1);
        }
        *fli = (char*) malloc(col_st*60);
        gets(fli[0]);
        for (i=0; i<col_st; i++)
        {
            printf("vvedite %d stroku: ", i+1);
            gets(fli);
        }
        for (i=0; i<col_st; i++) puts(fli);
    }
    if(ch==50)
    {
        f = fopen("temp.txt", "rt+");
        if (f == NULL)
        printf("Oshibka otkrytiya faila s kodom %d\n",errno );
        printf("\nSchytivanie s faila\nSchytivaetsya maximum %d strok\n", ST);
        *fli = (char*) malloc(ST*60);
        for (i=0; i<ST; i++)
        {
            fgets(fli, 80, f);
            printf("%s\n", fli);
            if(feof(f)) i=ST;
            col_st++;
        }
    }
    printf("\n-----Press enter!------\n");
    getch();
    for(i=0;i<col_st;i++)
    for(j=0;j<13;j++)
    fli=modString(fli, predl[j], zamen[j]);
    for (i=0; i<col_st; i++) printf("%s\n", fli);
    getch();
    free(fli);
}


если кому-либо будет непонятно, что делает та или иная переменная - спрашивайте))
297
30 января 2010 года
koodeer
1.2K / / 02.05.2009
Честно говоря, я в замешательстве: не припоминаю в русском языке предлога "од". // Grammar Nazi


Навскидку могу предложить задавать предлоги с пробелом:
 
Код:
char predl[13][7]={"v ","k ","s " ... etc
Тогда слоги внутри слова не будут с ними совпадать.
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
после предлогов могут быть и запятые.... кстати, од - действительно нет... Есть "от", что-то я напутал)))
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
нерабочий пример:
Доведем до безумства перед смертью - на входе
Доведем !! безумств! !!!!! смертью - на выходе

минусы - в конце слова "а" посчитало предлогом;
Некоторые предлоги в начале не считывает (Например "По");
некоторые строки из файла вообще не прочитались
12K
30 января 2010 года
Ghox
297 / / 26.07.2009
Прежде всего - программный код нужно заключать в теги CODE, а не QUOTE.
Цитата: Iworb
Написал программу, которая ищет во всех строках предлоги и заменяет их на восклицательные знаки по количеству символов. Но вот незадача - функцию поиска-замены я брал не свою (брал отсюда),


Помню-помню. :) Вот только вы не лучший вариант функции modString взяли - там в конце концов получился вариант, который был одобрен Kogrom'ом, лучше уж его было использовать (хотя в нем также будут описанные вами проблемы, и его вам также пришлось бы переделывать под ваши нужды)

Цитата: Iworb
поэтому и возникли проблемы:
например есть слово "проводник" и предлог "од", так вот он слово "проводник" преобразует в "пров!!ник". Нужно реализовать поиск предлогов, учитывая, что после них должен идти разделитель. Массив разделителей указан, но как реализовать - ума не приложу.


Но подскажу по тому варианту который вы взяли. Смотрим следующий фрагмент кода (немного прокомментировал):

Код:
// выделяется память под временный массив позиций,
    // с которых начинаются вхождения заменяемой строки
    numpos = (int*)malloc(sizeof(int) * (originalStringLength / strReplacedLength + 1));
    for(i = 0; i <= originalStringLength - strReplacedLength; ++i)
    {
        j = 0;
        // в этом цикле производится сравнение подстроки, начинающейся с позиции i, с заменяемой строкой
        while(j < strReplacedLength && string[i + j] == strReplaced[j])
            ++j;
        if(j == strReplacedLength /* текущая подстрока является заменяемой*/ )
        {
            // помещаем текущую позицию i в массив numpos:
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }
    }

Здесь, в случае обнаружения что текущая строка совпадает с заменяемой, можно добавить дополнительную проверку - следует ли в исходной строке, за заменяемой подстрокой, символ-разделитель. Если да - то тогда помещаем i в массив numpos. Сделать это можно, например, с помощью функции strchr из библиотеки string, проверяя, входит ли следующий (за проверяемой подстрокой) символ в строку символов-разделителей, только тогда строку разделителей нужно задать не в виде двумерного массива, как у вас сделано, а в виде обычной строки (только терминальный символ придется исключить):
 
Код:
char* razdel = ",. !?()\"";

Эту строку можно передавать в функцию modString отдельным аргументом, либо задать как глобальную переменную и использовать ее внутри функции modString. И в функции modString, используя strchr, проверять символ на вхождение в эту строку разделителей, и еще наверно отдельно учесть случай, что этот символ может быть терминальным символом.
Т.е. должно получиться что-то вроде такого:
 
Код:
if(j == strReplacedLength &&
               (/*здесь вызов strchr с аргументами razdel и string*/
                || string == '\0')
        )
        {
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }

Цитата: Iworb
Некоторые предлоги в начале не считывает (Например "По");


В смысле - не производит замену, если некоторые буквы отличаются регистром? Ну так это понятно почему: буквы 'П' и 'п' - это разные символы, и поэтому операция сравнения string[i + j] == strReplaced[j] в цикле while дает false. Чтобы без учета регистра сравнивать - можно использовать функцию tolower из string:

 
Код:
while(j < strReplacedLength && tolower(string[i + j]) == tolower(strReplaced[j]))
            ++j;
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
Цитата: Ghox
В смысле - не производит замену, если некоторые буквы отличаются регистром? Ну так это понятно почему: буквы 'П' и 'п' - это разные символы, и поэтому операция сравнения string[i + j] == strReplaced[j] в цикле while дает false. Чтобы без учета регистра сравнивать - можно использовать функцию tolower из string:




если я не ошибаюсь, то ф-ция tolower объявлена не в string.h, а в ctype.h

но даже после всего вышеперечисленного программа не реагирует. Вот переделал код по Вашим рекомендациям:

Код:
#include<errno.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define ST 10

char* razdel = ",. !?()\"";

char* modString(char *string, char *strReplaced, char *strReplacedBy)
{
    int originalStringLength, strReplacedLength, strReplacedByLength;
    int posReplacingCount, posReplacingNumber;
    int i, j, k;
    int *numpos;
    char *result;
    originalStringLength = strlen(string);
    strReplacedLength = strlen(strReplaced);
    strReplacedByLength = strlen(strReplacedBy);
    posReplacingCount = 0;
    numpos = (int*)malloc(sizeof(int) * (originalStringLength / strReplacedLength + 1));
    for(i = 0; i <= originalStringLength - strReplacedLength; ++i)
    {
        j = 0;
        while((j<strReplacedLength)&&(tolower(string[i + j])==tolower(strReplaced[j])))
            ++j;
        if((j==strReplacedLength)&&(strchr(string,razdel))||(string=='\0'))
        {
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }
    }
    if(!posReplacingCount)
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + 1));
        strcpy(result, string);
    }
    else
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + (strReplacedByLength - strReplacedLength) * posReplacingCount + 1));
        for(i = 0, j = 0, posReplacingNumber = 0; i < originalStringLength; ++i, ++j)
            if(posReplacingNumber == posReplacingCount || numpos[posReplacingNumber] > i)
                result[j] = string;
            else
            {
                for(k = 0; k < strReplacedByLength; ++k, ++j)
                    result[j] = strReplacedBy[k];
                i+= strReplacedLength - 1;
                --j;
                ++posReplacingNumber;
            }
        for( ; i < originalStringLength; ++i, ++j)
        result[j] = string;
        result[j] = '\0';
    }
    free(numpos);
    return result;
}

void main()
{
    FILE *f;
    char *fli[ST], *pch, *ptr;
    char ch, *p;
    char predl[13][7]={"v","k","s","a","do","po","iz","na","ot","bez","pri","pered","cherez"},
         zamen[13][7]={"!","!","!","!","!!","!!","!!","!!","!!","!!!","!!!","!!!!!","!!!!!!"};
    int i, col_st=0, j, k;
    clrscr();
    printf("vyberite metod vvoda:\n1 - s klaviatury\n2 - s faila temp.txt\n");
    ch=getch();
    if(ch==49)
    {
        printf("\nVvod s klaviatury\n");
        printf("\nSkoka budet strok:");
        scanf("%d", &col_st);
        if((col_st<1)||(col_st>ST))
        {
            printf("error! Dolzhno byt` ne men`she 1 i ne bol`she 10 strok!");
            exit(-1);
        }
        *fli = (char*) malloc(col_st*60);
        gets(fli[0]);
        for (i=0; i<col_st; i++)
        {
            printf("vvedite %d stroku: ", i+1);
            gets(fli);
        }
        for (i=0; i<col_st; i++) puts(fli);
    }
    if(ch==50)
    {
        f = fopen("temp.txt", "rt+");
        if (f == NULL)
        printf("Oshibka otkrytiya faila s kodom %d\n",errno );
        printf("\nSchytivanie s faila\nSchytivaetsya maximum %d strok\n", ST);
        *fli = (char*) malloc(ST*60);
        for (i=0; i<ST; i++)
        {
            fgets(fli, 80, f);
            printf("%s\n", fli);
            if(feof(f)) i=ST;
            col_st++;
        }
    }
    printf("\n-----Press enter!------\n");
    getch();
    for(i=0;i<col_st;i++)
    for(j=0;j<13;j++)
    fli=modString(fli, predl[j], zamen[j]);
    for (i=0; i<col_st; i++) printf("%s\n", fli);
    getch();
    free(fli);
}


а за тег звиняйте)) немного не тот поставил и не заметил....
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
выдает ошибку, связанную с strchr, так как вторым аргументом должно являтся целое число - номер младшего байта
char strchr(const char *str, int ch);

Функция strchr() возвращает указатель на первое вхождение младшего байта параметра ch в строку str. Если указанный символ не найден, возвращается нулевой указатель.
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
Цитата:
Здесь, в случае обнаружения что текущая строка совпадает с заменяемой, можно добавить дополнительную проверку - следует ли в исходной строке, за заменяемой подстрокой, символ-разделитель. Если да - то тогда помещаем i в массив numpos. Сделать это можно, например, с помощью функции strchr из библиотеки string, проверяя, входит ли следующий (за проверяемой подстрокой) символ в строку символов-разделителей, только тогда строку разделителей нужно задать не в виде двумерного массива, как у вас сделано, а в виде обычной строки (только терминальный символ придется исключить):



или мне кажеться, или программа все-таки стравнивает текущий символ?:confused:

12K
30 января 2010 года
Ghox
297 / / 26.07.2009
Цитата: Iworb
если я не ошибаюсь, то ф-ция tolower объявлена не в string.h, а в ctype.h


Да, это я ошибся уже - невнимательно посмотрел в справочнике, думал что все символьные / строковые функции из C находятся в string.h. На самом деле верно вы говорите - библиотека ctype.h.

Цитата: Iworb
но даже после всего вышеперечисленного программа не реагирует. Вот переделал код по Вашим рекомендациям:


Ошибки в этом фрагменте (частично по моей немного неверной подсказке, частично - ваши):

 
Код:
if((j == strReplacedLength)&&strchr[COLOR="Red"](razdel,string|| string == '\0')[/COLOR])
        {
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }

Тут во-первых - я вам неправильно сказал: вызывать strchr и сравнивать с '\0' нужно не для string, а string[i + j]. Во-вторых, вы неправильно задали список аргументов strchr - посмотрите как вы ее сейчас вызываете (выделил красным).
В правильном варианте должно быть как-то так:
 
Код:
if((j == strReplacedLength)&& (strchr(razdel,string[i+j]) || string[i+j] == '\0'))
        {
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
и все равно есть где-то неправильный код....
Вызываем текст из файла. В файле следующее:
Цитата:
I v nashem dome budet prazdnik
A bez deneg - nikuda
Dovedem do bezumstva pered smehom
Dostanem iz ada cherez vremya
Priletim na parashute
Po nevedomym tropinkam


После работы программы получаем следующее:

Цитата:
I ! nashem dome budet prazdnik

[COLOR="Red"]!! nevedomym tropinkam[/COLOR]
Dovedem !! bezumstv[COLOR="Red"]![/COLOR] !!!!! smehom

[COLOR="#ff0000"]m !! bezumst!! !!!!! smehom[/COLOR]

Priletim n[COLOR="#ff0000"]![/COLOR] parashute

!! nevedomym tropinkam


крастным выделил там, где такого быть не должно...

вот что должно быть на выходе:

Цитата:
I ! nashem dome budet prazdnik
A !!! deneg - nikuda
Dovedem !! bezumstva !!!!! smehom
Dostanem !! ada !!!!!! vremya
Priletim !! parashute
!! nevedomym tropinkam

12K
30 января 2010 года
Ghox
297 / / 26.07.2009
Цитата: Iworb
выдает ошибку, связанную с strchr, так как вторым аргументом должно являтся целое число - номер младшего байта
char strchr(const char *str, int ch);

Функция strchr() возвращает указатель на первое вхождение младшего байта параметра ch в строку str. Если указанный символ не найден, возвращается нулевой указатель.


Что за ошибка-то? Ошибка компиляции? По идее символ, являющийся переменной char, должен автоматически преобразоваться из char в int, при вызове функции... Но если автоматического преобразования не происходит - то тогда можно попробовать вместо string[i + j] поставить (int)string[i + j].
Хотя может быть ошибка у вас из-за того что вы неправильно вызов функции написали (со скобками напутали).

Цитата: Iworb
или мне кажеться, или программа все-таки стравнивает текущий символ?:confused:


Да, сравнивался текущий - см. мой пост выше.

12K
30 января 2010 года
Ghox
297 / / 26.07.2009
Цитата: Iworb
и все равно есть где-то неправильный код....
Вызываем текст из файла. В файле следующее:

После работы программы получаем следующее:

крастным выделил там, где такого быть не должно...


А, да... Надо сравнивать на вхождение в строку разделителей не только символ string[i + j], следующий за проверяемой подстрокой, но и символ, предшествующий подстроке - символ string[i - 1]. Как это сделать - уж это я думаю теперь догадаетесь сами :) (через ту же strchr). Только учесть надо отдельно случай, когда i = 0.

9
30 января 2010 года
Lerkin
3.0K / / 25.03.2003
Не пойму, проблема в проверке на пробел до и после обнаруженного предлога?
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
да, проблема с предыдущим символом немного облегчила, но всеравно выходит такой текст:

Цитата:
I ! nashem dome budet prazdnik

Po nevedomym tropinkam
Dovedem !! bezumstva !!!!! smehom

m !! bezumstva !!!!! smehom

Priletim !! parashute

Po nevedomym tropinkam

53K
30 января 2010 года
Iworb
17 / / 30.01.2010
Цитата: Lerkin
Не пойму, проблема в проверке на пробел до и после обнаруженного предлога?


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

53K
30 января 2010 года
Iworb
17 / / 30.01.2010
Цитата: Ghox
А, да... Надо сравнивать на вхождение в строку разделителей не только символ string[i + j], следующий за проверяемой подстрокой, но и символ, предшествующий подстроке - символ string[i - 1]. Как это сделать - уж это я думаю теперь догадаетесь сами :) (через ту же strchr). Только учесть надо отдельно случай, когда i = 0.



это понял, но вот отдельный случай для нуля немного не дошло....
вот кусочек кода:

Код:
if((j==strReplacedLength)&&((strchr(razdel,string[i+j])||(string == '\0'))))
        {
            if(i>0)
            {
                if(strchr(razdel,string[i-1]))
                {
                    numpos[posReplacingCount++] = i;
                    i += strReplacedLength - 1;
                }
            }
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }


ведь если i=0, то нет необходимости сравнивать предыдущий элемент
12K
30 января 2010 года
Ghox
297 / / 26.07.2009
По-моему, вы неправильно память выделяете под динамический массив строк...
Код:
char *fli[ST], *pch, *ptr;
// ...
    if(ch==50)
    {
        f = fopen("temp.txt", "rt+");
        if (f == NULL)
        printf("Oshibka otkrytiya faila s kodom %d\n",errno );
        printf("\nSchytivanie s faila\nSchytivaetsya maximum %d strok\n", ST);
        *fli = (char*) malloc(ST*60); // думаю что нужно это удалить
        for (i=0; i<ST; i++)
        {
            // а здесь под отдельную строку выделить память:
            fli = (char*)malloc(60 * sizeof(char));
            fgets(fli, 80, f);
            printf("%s\n", fli);
            if(feof(f)) i=ST;
            col_st++;
        }
    }

Ну и еще в циклах, где производится вызов modString, я так бы подправил (объявив в начале функции вспомогательную переменную char *tmp):
 
Код:
for(i=0;i<col_st;i++)
        for(j=0;j<13;j++)
        {
            tmp = modString(fli, predl[j], zamen[j]);
            free(fli);
            fli = tmp;
        }

Хотя как-то не очень мне нравится - для каждой замены выделять / освобождать память...
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
да, за ошибку с выделением памяти огромнейшее спасибо, сам бы я не заметил)))
Но всеже, теперь появились другие баги
Цитата:
I !!nashem dome budet prazdnik

[COLOR="Red"]! !!!!!!neg - nikuda[/COLOR]

[COLOR="Red"]Dovedem !!!!ezumstv! !!!!!!!!!!om[/COLOR]

[COLOR="#ff0000"]Dostanem !!!!d! !!!!!!!!!!!!a[/COLOR]

Priletim n[COLOR="#ff0000"]![/COLOR] parashute

!! nevedomym tropinkam



"v " заменило на "!!". Должно на "! "
также крастным выделил проблемы...

53K
30 января 2010 года
Iworb
17 / / 30.01.2010
код на текущий момент:
Код:
#include<errno.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define ST 10

const char *razdel=",. !?()\"";

char* modString(char *string, char *strReplaced, char *strReplacedBy)
{
    int originalStringLength, strReplacedLength, strReplacedByLength;
    int posReplacingCount, posReplacingNumber;
    int i, j, k;
    int *numpos;
    char *result;
    originalStringLength = strlen(string);
    strReplacedLength = strlen(strReplaced);
    strReplacedByLength = strlen(strReplacedBy);
    posReplacingCount = 0;
    numpos = (int*)malloc(sizeof(int) * (originalStringLength / strReplacedLength + 1));
    for(i = 0; i <= originalStringLength - strReplacedLength; ++i)
    {
        j = 0;
        while((j<strReplacedLength)&&(tolower(string[i + j])==tolower(strReplaced[j])))
            ++j;
    if((j==strReplacedLength)&&((strchr(razdel,string[i+j])||(string == '\0'))))
        {
            if(i>0)
            {
                if(strchr(razdel,string[i-1]))
                {
                    numpos[posReplacingCount++] = i;
                    i += strReplacedLength - 1;
                }
            }
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }
    }
    if(!posReplacingCount)
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + 1));
        strcpy(result, string);
    }
    else
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + (strReplacedByLength - strReplacedLength) * posReplacingCount + 1));
        for(i = 0, j = 0, posReplacingNumber = 0; i < originalStringLength; ++i, ++j)
            if(posReplacingNumber == posReplacingCount || numpos[posReplacingNumber] > i)
                result[j] = string;
            else
            {
                for(k = 0; k < strReplacedByLength; ++k, ++j)
                    result[j] = strReplacedBy[k];
                i+= strReplacedLength - 1;
                --j;
                ++posReplacingNumber;
            }
        for( ; i < originalStringLength; ++i, ++j)
        result[j] = string;
        result[j] = '\0';
    }
    free(numpos);
    return result;
}

void main()
{
    FILE *f;
    char *fli[ST], *tmp;
    char ch, *p;
    char predl[13][7]={"v","k","s","a","do","po","iz","na","ot","bez","pri","pered","cherez"},
         zamen[13][7]={"!","!","!","!","!!","!!","!!","!!","!!","!!!","!!!","!!!!!","!!!!!!"};
    int i, col_st=0, j, k;
    clrscr();
    printf("vyberite metod vvoda:\n1 - s klaviatury\n2 - s faila temp.txt\n");
    ch=getch();
    if(ch==49)
    {
        printf("\nVvod s klaviatury\n");
        printf("\nSkoka budet strok:");
        scanf("%d", &col_st);
        if((col_st<1)||(col_st>ST))
        {
            printf("error! Dolzhno byt` ne men`she 1 i ne bol`she 10 strok!");
            exit(-1);
        }
        *fli = (char*) malloc(col_st*60);
        gets(fli[0]);
        for (i=0; i<col_st; i++)
        {
            printf("vvedite %d stroku: ", i+1);
            gets(fli);
        }
        for (i=0; i<col_st; i++) puts(fli);
    }
    if(ch==50)
    {
        f = fopen("temp.txt", "rt+");
        if (f == NULL)
        printf("Oshibka otkrytiya faila s kodom %d\n",errno );
        printf("\nSchytivanie s faila\nSchytivaetsya maximum %d strok\n", ST);
        for (i=0; i<ST; i++)
        {
            fli = (char*)malloc(60 * sizeof(char));
            fgets(fli, 80, f);
            printf("%s\n", fli);
            if(feof(f)) i=ST;
            col_st++;
        }
    }
    printf("\n-----Press enter!------\n");
    getch();
    for(i=0;i<col_st;i++)
        for(j=0;j<13;j++)
        {
            tmp = modString(fli, predl[j], zamen[j]);
            free(fli);
            fli = tmp;
        }
    for (i=0; i<col_st; i++) printf("%s\n", fli);
    getch();
    free(fli);
}
12K
30 января 2010 года
Ghox
297 / / 26.07.2009
Цитата: Iworb
это понял, но вот отдельный случай для нуля немного не дошло....
вот кусочек кода:
Код:
if((j==strReplacedLength)&&((strchr(razdel,string[i+j])||(string == '\0'))))
        {
            if(i>0)
            {
                if(strchr(razdel,string[i-1]))
                {
                    numpos[posReplacingCount++] = i;
                    i += strReplacedLength - 1;
                }
            }
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }


ведь если i=0, то нет необходимости сравнивать предыдущий элемент


Здесь можно все проверки в одном условии сделать:

 
Код:
if(j==strReplacedLength
        && (string[i+j] == '\0' || strchr(razdel,string[i+j]))
        && (i == 0 || strchr(razdel,string[i-1])))
        {
        numpos[posReplacingCount++] = i;
        i += strReplacedLength - 1;
        }
53K
30 января 2010 года
Iworb
17 / / 30.01.2010
все, проблема решилась последним постом!)) Огромное спасибо выражаю пользователю Ghox, неравнодушному к проблеме. Для заинтересованных выкладываю рабочий код:
Код:
#include<errno.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#define ST 10

const char *razdel=",. !?()\"";

char* modString(char *string, char *strReplaced, char *strReplacedBy)
{
    int originalStringLength, strReplacedLength, strReplacedByLength;
    int posReplacingCount, posReplacingNumber;
    int i, j, k;
    int *numpos;
    char *result;
    originalStringLength = strlen(string);
    strReplacedLength = strlen(strReplaced);
    strReplacedByLength = strlen(strReplacedBy);
    posReplacingCount = 0;
    numpos = (int*)malloc(sizeof(int) * (originalStringLength / strReplacedLength + 1));
    for(i = 0; i <= originalStringLength - strReplacedLength; ++i)
    {
        j = 0;
        while((j<strReplacedLength)&&(tolower(string[i + j])==tolower(strReplaced[j])))
            ++j;
    if((j==strReplacedLength)
        &&((string[i+j]=='\0')||(strchr(razdel,string[i+j])))
        &&((i==0)||(strchr(razdel,string[i-1]))))
        {
            numpos[posReplacingCount++] = i;
            i += strReplacedLength - 1;
        }
    }
    if(!posReplacingCount)
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + 1));
        strcpy(result, string);
    }
    else
    {
        result = (char*)malloc(sizeof(char) * (originalStringLength + (strReplacedByLength - strReplacedLength) * posReplacingCount + 1));
        for(i = 0, j = 0, posReplacingNumber = 0; i < originalStringLength; ++i, ++j)
            if(posReplacingNumber == posReplacingCount || numpos[posReplacingNumber] > i)
                result[j] = string;
            else
            {
                for(k = 0; k < strReplacedByLength; ++k, ++j)
                    result[j] = strReplacedBy[k];
                i+= strReplacedLength - 1;
                --j;
                ++posReplacingNumber;
            }
        for( ; i < originalStringLength; ++i, ++j)
        result[j] = string;
        result[j] = '\0';
    }
    free(numpos);
    return result;
}

void main()
{
    FILE *f;
    char *fli[ST], *tmp;
    char ch, *p;
    char predl[13][7]={"v","k","s","a","do","po","iz","na","ot","bez","pri","pered","cherez"},
         zamen[13][7]={"!","!","!","!","!!","!!","!!","!!","!!","!!!","!!!","!!!!!","!!!!!!"};
    int i, col_st=0, j, k;
    clrscr();
    printf("vyberite metod vvoda:\n1 - s klaviatury\n2 - s faila temp.txt\n");
    ch=getch();
    if(ch==49)
    {
        printf("\nVvod s klaviatury\n");
        printf("\nSkoka budet strok:");
        scanf("%d", &col_st);
        if((col_st<1)||(col_st>ST))
        {
            printf("error! Dolzhno byt` ne men`she 1 i ne bol`she 10 strok!");
            exit(-1);
        }
        *fli = (char*) malloc(col_st*60);
        gets(fli[0]);
        for (i=0; i<col_st; i++)
        {
            printf("vvedite %d stroku: ", i+1);
            gets(fli);
        }
        for (i=0; i<col_st; i++) puts(fli);
    }
    if(ch==50)
    {
        f = fopen("temp.txt", "r+");
        if (f == NULL)
        printf("Oshibka otkrytiya faila s kodom %d\n",errno );
        printf("\nSchytivanie s faila\nSchytivaetsya maximum %d strok\n", ST);
        for (i=0; i<ST; i++)
        {
            fli = (char*)malloc(60 * sizeof(char));
            fgets(fli, 80, f);
            printf("%s\n", fli);
            if(feof(f)) i=ST;
            col_st++;
        }
    }
    printf("\n-----Press enter!------\n");
    getch();
    for(i=0;i<col_st;i++)
        for(j=0;j<13;j++)
        {
            tmp = modString(fli, predl[j], zamen[j]);
            free(fli);
            fli = tmp;
        }
    for (i=0; i<col_st; i++) printf("%s\n", fli);
    printf("\nDopisat` text v fail?(y/n)\n");
    ch=getch();
    if((ch==121)||(ch==13))
    {
        for(i=0; i<col_st;i++)
        fputs(fli, f);
    }
    printf("Gotovo!");
    getch();
    free(fli);
    if (fclose(f) < 0)
    {
        perror("\nError to close file!!!");
    }
}


модераторы, пожалуйста, не удаляйте этот пост с благодарностью, ибо в нем заключен последний рабочий вариант программы
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог