Создание пользовательской функции tr.c

void tr_str(char s[], char news[]){
int c;
size_t k =0;
    while ((c = getchar()) != EOF)
    {
        for(k=0; k < strlen(s);k++)
        {                   
            if(c == s[k])
            {
                c = news[k];
            }
        }
        putchar(c);
    }
}

Это моя функция перевода, которая в настоящее время принимает два аргумента из командной строки и использует эти буквы для переключения первого набора на второй набор. Я только что обнаружил проблему, из-за которой она не работает, если два аргумента имеют разную длину. Что должно произойти, так это то, что если 1-й аргумент имеет длину 3 символа, а второй - длину 2 символа, ко второму аргументу добавляется третий символ, и он должен быть равен последнему сохраненному в нем символу. Пример: arg1(a,b,c); аргумент2(х,у); При использовании arg2 становится arg2(x,y,y);

Спасибо за вашу помощь.


c io tr
person TheUnknown    schedule 05.02.2015    source источник
comment
Посмотрите на strstr(), strchr(), strspn()?   -  person EOF    schedule 05.02.2015
comment
Ни одна из этих функций не идеальна, поскольку вам действительно нужна функция, которая является size_t indexof(char *haystack, int needle), но лучшее, что вы получаете, это char *strchr(char *haystack, int needle), поэтому вам нужно вычислить индекс, вычитая указатели.   -  person EOF    schedule 05.02.2015
comment
Я как бы понимаю, о чем вы говорите. Количество указателей показывает, сколько фактических значений хранится в массиве правильно? Используя это, я думаю, я могу сделать цикл, чтобы заполнить оставшееся пространство последним встречающимся символом. Есть ли функция для получения последнего символа строки?   -  person TheUnknown    schedule 05.02.2015


Ответы (1)


Если вы просто хотите, чтобы ваш код работал без какой-либо оптимизации, вам нужно сравнить k с strlen(news), прежде чем выбирать char в новостях. Предполагается, что в новости есть хотя бы один символ.

void tr_str(char s[], char news[]){
int c;
size_t k =0;
    while ((c = getchar()) != EOF)
    {
        for(k=0; k < strlen(s);k++)
        {                   
            if(c == s[k])
            {
                if (k >= strlen(news))
                    c = news[strlen(news) - 1)];
                else
                    c = news[k];
                break; // Need a break here, else c could be found again in s and translated again.
            }
        }
        putchar(c);
    }
}

Повторение последнего символа в новостях для предотвращения повторения теста в цикле — хорошая идея, но вы не должны напрямую изменять news[], за исключением случаев, когда вы уверены, что в каждом случае новости находятся в достаточно большой памяти, доступной для записи, и даже тогда это все еще плохая практика ИМО. Сделайте копию новости и работайте с ней лучше.

void tr_str(char s[], char news[]){
int c;
size_t k = 0;
size_t sSize = strlen(s);
size_t newsSize = strlen(news);
char *newsCopy;
int preventsMemoryLeak = 0;

    if (newsSize < sSize)
    {
        // Duplicates news in a large enough memory. No need a zero at end of this copy.
        newsCopy = malloc(sSize);
        memcpy(newsCopy, news, newsSize);
        // Fills the remaining with a copy of the last char
        memset(newsCopy + newsSize, news[newsSize - 1], sSize - newsSize);

        preventsMemoryLeak = 1;
    }
    else
    {
        newsCopy = news;
    }

    while ((c = getchar()) != EOF)
    {
        for(k = 0; k < sSize; k++)
        {                   
            if(c == s[k])
            {
                c = newsCopy[k];
                break;
            }
        }
        putchar(c);
    }

    if (preventsMemoryLeak == 1) free(newsCopy);
}
person Joël Hecht    schedule 08.02.2015