Помогите отловить ошибку

Тема в разделе "Общие вопросы по С и С++", создана пользователем Linko, 10 янв 2007.

Статус темы:
Закрыта.
  1. Linko

    Linko Гость

    Репутация:
    0
    Здравствуйте, уважаемые!
    Пытаюсь написать программу для замены символов в строке, но не получается, появилась плавающая ошибка. Вот там где я отметил стрелочкой, после этого происходит добавление левых символов в строку, не всегда причем, понять в чем проблема не могу. А когда происходит вызов замены для последней пары из структуры - так там вообще сразу получается мусор.
    Проблемы возникают при замене с 'r' на 'р', текст превращается в :
    Код (Text):
    был: Thиs иs a '#URL#' strиng "#ID#" HA-HA-HA, #ID# for testиng #IDCODE#---
    стал: Thиs иs a '#URL#' stЪЪЪЪриng "#ID#" HA-HA-HA, #ID# for testиng #IDCODE#---
    Код (Text):
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <memory.h>

    typedef struct
    {
    char from[32];
    char to[64];
    } tagStruct;

    char * tagReplacer(char *src, tagStruct * tagS, int count)
    {
    bool replaced=true;
    char *tmp=NULL;
    char *res=NULL;
    char *pch=NULL;
    tmp=(char*) malloc(sizeof(char)+1);
    res=(char*) malloc(sizeof(char)+1);
    res=(char*)realloc(res,((strlen(src))*sizeof(char*)));
    strcpy (res,src);
    for(int i=0;i<count;i++) {
    while (replaced) {
    int lenres=strlen(res);
    if(pch = strstr (res,tagS[i].from)) {
    replaced=true;
    tmp=(char*)realloc(tmp, (lenres-strlen(pch)+1)*sizeof(char));
    strncpy(tmp,res,lenres-strlen(pch));
    tmp=(char*)realloc(tmp, (strlen(tmp)+strlen(tagS[i].to)+1)*sizeof(char));
    strncat(tmp,tagS[i].to,strlen(tagS[i].to));
    if((strlen(tmp))<(lenres+strlen(tagS[i].to)-strlen(tagS[i].from))){
    -->>>         tmp=(char*)realloc(tmp, (lenres+strlen(tagS[i].to)-strlen(tagS[i].from)-1)*sizeof(char));
    for(int z=(strlen(res)-strlen(pch)+strlen(tagS[i].to));z<((strlen(res)));z++){
    tmp[strlen(tmp)]=res[z];
    }
    }
    }
    else {
    replaced=false;
    }
    if(replaced) {
    res=NULL;
    res=(char*)realloc(res,(strlen(tmp)+1));
    strncpy (res,tmp,strlen(tmp));
    tmp=NULL;
    pch=NULL;
    }
    }
    replaced=true;
    }
    return res;
    }

    int main ()
    {
    tagStruct *tagStr=NULL;
    tagStr=(tagStruct*) malloc(sizeof(tagStruct));
    strcpy(tagStr[0].from,"i");
    strcpy(tagStr[0].to,"и");
    tagStr=(tagStruct*)realloc(tagStr, (sizeof(tagStruct))*2);
    strcpy(tagStr[1].from,"r");
    strcpy(tagStr[1].to,"р");
    tagStr=(tagStruct*)realloc(tagStr, (sizeof(tagStruct))*3);
    strcpy(tagStr[2].from,"t");
    strcpy(tagStr[2].to,"т");
    tagStr=(tagStruct*)realloc(tagStr, (sizeof(tagStruct))*4);
    strcpy(tagStr[3].from,"Th");
    strcpy(tagStr[3].to,"В");

    const char *foo=tagReplacer("This is a '#URL#' string \"#ID#\" HA-HA-HA, #ID# for testing #IDCODE#---",tagStr,4);
    printf("%s\n",foo);
    }
     
  2. European

    Репутация:
    0
    Регистрация:
    4 сен 2006
    Сообщения:
    2.566
    Симпатии:
    1
    Чтобы не иметь таким странных проблем лучше использовать строки из стандартной библиотеки C++

    Надеюсь, что двойное использование main - опечатка?
     
  3. Linko

    Linko Гость

    Репутация:
    0
    Да, извините, двойной main это опечатка при копировании.
    А что подразумевается под стандатрными? STL?
    Мне надо использование именно char и структуры.
     
  4. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    а куча realloc тоже условие?
     
  5. zubr

    zubr Гость

    Репутация:
    0
    Первое что бросается в глаза, выражение: res=(char*)realloc(res,((strlen(src))*sizeof(char*)));
    Ты пытаешься выделить память не под 1-байтовый тип char, а под указатель char*, а это 4-байтовый тип.
     
  6. Linko

    Linko Гость

    Репутация:
    0
    "Не стреляйте в пианиста, он играет как умеет".
    Так я стараюсь поэффективнее использовать память и не быть привязанным к размерам массивов.

    Это ничего не меняет, по крайней мере - в моем случае, я пробовал...
     
  7. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Виноват, сходу не понял для чего count. Исправился.

    Как ты думаешь, ты сможешь разобраться в своем коде через полгода, если ты сейчас даже ошибку найти в нем не можешь? Сколько ты собрался памяти экономить? Вряд-ли у тебя будут строки длиной больше 1М использоваться. Стоит твоя экономия памяти проблем с чтением кода? И кстати, попробуй поменять в строке "мама" 'а' на 'м' и наоборот :)

    Код (Text):
    char * tagReplacer(char *src, tagStruct * tagS, int count)
    {
    if (!src || !tagS || !*src)
    return NULL;
    if (count<=0)
    return strdup(src);
    int nOrgLen = strlen(src);
    int nMaxLen = strlen(tagS[0]->to);
    for (int i=1; i<count; i++)
    {
    int l = strlen(tagS[i]->to);
    if (l>nMaxLen)
    nMaxLen = l;
    }
    char* szRet = (char*)malloc(max(nOrgLen, nOrgLen*nMaxLen)+1);
    char* szCur = szRet;
    while (*src)
    {
    BOOL bDone = FALSE;
    for (i=0; i<nCount; i++)
    {
    if (!strcmp(str, tagS[i]->from))    // got it!
    {
    if (*tagS[i]->to)
    {
    strcpy(szCur, tagS->to);
    szCur += strlen(tagS->to);
    }
    str += strlen(tagS[i]->from);
    bDone = TRUE;
    break;
    }
    }
    if (!bDone)
    {
    *szCur = *str;
    szCur++;
    str++;
    }
    }
    *szCur=0;
    return szRet;
    }
     
  8. Linko

    Linko Гость

    Репутация:
    0
    А ты в чем собирал это и тестировал? У меня к пример нет max, в строке которую я оставил.
    P.S.: В коде намеренно сделано только ошибок? :) str у меня тоже нет.
     
  9. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    :) ну прям собирал и тестировал :) Прямо тут писал, уж извините :) Ну с max я думаю проблем не будет, а str - это src должно быть, что-то меня переклинило в середине :) Код просто как пример давал - я на С уже сто лет не писал.
     
  10. Linko

    Linko Гость

    Репутация:
    0
    Все таки с max есть проблемы :)
    Я тут даже не представляю, какую роль оно может играть :)
     
  11. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    эээ, тогда так:
    Код (Text):
    if (nMaxLen<1)
    nMaxLen = 1;
    char* szRet = (char*)malloc(nOrgLen*nMaxLen+1)
    И кстати, в чем смысл sizeof(char)? Вроде как char>1 только в C#. Или в голом С юникод просто так собирается, без всяких TCHAR, wchar, L и прочих?
     
  12. Linko

    Linko Гость

    Репутация:
    0
    Вся засада в том - что я это пишу под FreeBSD, используя компилятор g++42
    А в чем смысл - я точно не помню, но без этого периодически все начинало у меня глючить, когда то давно, глюки исчезли, а привычка осталась.

    Кстати, я так и не постиг - за что отвечает nCount :)
     
  13. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    nCount это count должен быть :) привычка :)
     
  14. Linko

    Linko Гость

    Репутация:
    0
    Да, я так и понял. :)
    Вообщем - буду ковырять то что получилось, а то с первого раза не заработало, уходит в бесконечный цикл :)
     
  15. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Ну ты меня прямо напугал, пришлось все-таки собрать и проверить :) Должен извинится, наляпал не глядя много, конечно, но в мелочах. Принципиальная ошибка одна всего - надо strncmp вместо strcmp.
    Код (Text):
    char * tagReplacer(char *src, tagStruct * tagS, int count)
    {
    if (!src || !tagS || !*src)
    return NULL;
    if (count<=0)
    return strdup(src);
    int nOrgLen = strlen(src);
    int nMaxLen = strlen(tagS[0].to);
    for (int i=1; i<count; i++)
    {
    int l = strlen(tagS[i].to);
    if (l>nMaxLen)
    nMaxLen = l;
    }
    if (nMaxLen<1)
    nMaxLen = 1;
    char* szRet = (char*)malloc(sizeof(char)*(nOrgLen*nMaxLen+1));
    char* szCur = szRet;
    while (*src)
    {
    BOOL bDone = FALSE;
    for (i=0; i<count; i++)
    {
    if (!strncmp(src, tagS[i].from, strlen(tagS[i].from)))  // got it!
    {
    if (*tagS[i].to)
    {
    strcpy(szCur, tagS[i].to);
    szCur += strlen(tagS[i].to);
    }
    src += strlen(tagS[i].from);
    bDone = TRUE;
    break;
    }
    }
    if (!bDone)
    {
    *szCur = *src;
    szCur++;
    src++;
    }
    }
    *szCur=0;
    return szRet;
    }
     
  16. Linko

    Linko Гость

    Репутация:
    0
    Блин, все отдам - когда узнаю что же все такое - max?
    У меня такого в юниксе нет :) И ни какого описания или намеков на это, как оно работает? :)
     
  17. grigsoft

    grigsoft Well-Known Member

    Репутация:
    0
    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Дык это - выбирает максимум :) но это из С++.
    Код (Text):
    #define max(a, b) ((a)>(b) ? (a) :(b))
     
  18. Linko

    Linko Гость

    Репутация:
    0
    Я в шоке - оно работает как часы! :)
    Спасибо, буду работать над собой :)
     
Загрузка...
Похожие Темы - Помогите отловить ошибку
  1. Sa1nt
    Ответов:
    3
    Просмотров:
    71
  2. Amfion
    Ответов:
    3
    Просмотров:
    109
  3. number27
    Ответов:
    0
    Просмотров:
    94
  4. Rina
    Ответов:
    0
    Просмотров:
    132
  5. maksiiimka
    Ответов:
    7
    Просмотров:
    166
Статус темы:
Закрыта.

Поделиться этой страницей