Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Где ошибка?


Автор: olegarh 7.9.2011, 12:59
Всем привет..

есть функция на вход которой подается дата (число месяц)
одна и та же дата может подаваться несколько раз например 03.05, след раз 03.05, а потом например 04.05.

нужно зафиксировать изменение даты и если она изменилась то выполнить некоторые действия

делаю так

Код

    static void OutXML (char* data)
    {

        static char* data1='\0';
        static bool fl=0;


                printf ("\nДата - %s",data);//когда дата меняется по идее data1 должна остаться старой, но получается что она равна data хотя никаких присваиваний я не делаю
        printf ("\nДата - %s",data1);
        printf ("\nфлаг - %d",fl);
    

        if ((data1!=data) && (fl==0))
        {
                        printf ("\nцикл1\n");//выполняем какие то действия
            data1=data;
            fl=1;
        }
        if ((data1==data) && (fl==0)){
            printf ("\nцикл2\n");//выполняем какие то действия
            
            fl=1;
        }
        if ((data1==data) && (fl==1))
        {
            printf ("\nцикл3\n");
            
        }
        if ((data1!=data) && (fl==1))
        {
            printf ("\nцикл4\n");
            data1=data;
            fl=0;
        }
    }


В итоге получается что программа один раз заходит в цикл1 потом крутиться в цикле3 даже если дата меняется. в чем дело не пойму.

Автор: rodnover 7.9.2011, 13:08
Как минимум:
1. за срок жизни переменной data вы не отвечаете, поэтому она может уничтожиться в любой момент, после возврата из данной функции и data1 будет указывать на мусор;
2. для решения этой проблемы нужно использовать копирование строк. Хотя бы функцию strcpy и выделять память под data
Код

    data = new char[size];

3. 
Код
data1==data
 - сравнивает указатели, а не строки. сравнивать char * можно так strcmp

Автор: boostcoder 7.9.2011, 13:08
Цитата(olegarh @  7.9.2011,  12:59 Найти цитируемый пост)
        static char* data1='\0';
        static bool fl=0;

ну так это же статики.

Автор: olegarh 7.9.2011, 13:14

rodnover, Это не меняет того что первые принты показывают что data = data1 хотя присваиваний там нет
это как то объяснить можете?

boostcoder, ии?? что не так?

Автор: rodnover 7.9.2011, 13:18
Потому что вам везет и адрес куда указывает data не меняется, вы просто меняете текст расположенный по адресу указываемому data.

Для быстрого примера попробуйте:

Код

    static void OutXML (char* data)
    {
        static char data1[1000]; //Указываем область, которой точно хватит
        static bool fl=0;
//                printf ("\nДата - %s",data);//когда дата меняется по идее data1 должна остаться старой, но получается что она равна data хотя никаких присваиваний я не делаю
//        printf ("\nДата - %s",data1);
//        printf ("\nфлаг - %d",fl);
    
        if ((strcmp(data1, data)) && (fl==0)){ // Сравниваем текст, а не указатели
        {
                        printf ("\nцикл1\n");//выполняем какие то действия
            strcpy(data1, data); // Копируем сам текст, а не указатель
            fl=1;
        }
        if ((!strcmp(data1, data)) && (fl==0)){ // Сравниваем текст, а не указатели
            printf ("\nцикл2\n");//выполняем какие то действия
            
            fl=1;
        }
        if ((!strcmp(data1, data)) && (fl==1)) // Сравниваем текст, а не указатели
        {
            printf ("\nцикл3\n");
            
        }
        if ((strcmp(data1, data)) && (fl==1)) // Сравниваем текст, а не указатели
        {
            printf ("\nцикл4\n");
            data1=data;
            fl=0;
        }
    }


извиняюсь за возможные опечатки - копипаста. smile

Автор: olegarh 7.9.2011, 20:59
Попробывал, получилось что data1 на протяжении всей программы не изменилось и осталось равно начальному значению smile 

Еще варианты есть? smile 

Автор: Леопольд 8.9.2011, 07:37
olegarh, стоит попробовать http://cplusplus.com/reference/string/string/...

Автор: rodnover 8.9.2011, 08:19
Код


//============================================================================
// Name        : test.cpp
// Author      : rodnover
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

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

static void OutXML(char* data)
{
    static char data1[1000]; //Указываем область, которой точно хватит
    static bool fl = 0;
    //                printf ("\nДата - %s",data);//когда дата меняется по идее data1 должна остаться старой, но получается что она равна data хотя никаких присваиваний я не делаю
    //        printf ("\nДата - %s",data1);
    //        printf ("\nфлаг - %d",fl);

    if ((strcmp(data1, data)) && (fl == 0)) // При выполнении этого блока всегда выполняется блок, который чуть ниже, так как data1 будет равно data и fl установлен в 1
    { // Сравниваем текст, а не указатели
        printf("\nцикл1\n");//выполняем какие то действия
        strcpy(data1, data); // Копируем сам текст, а не указатель
        fl = 1;
    }
    if ((!strcmp(data1, data)) && (fl == 0))
    { // Сравниваем текст, а не указатели
        printf("\nцикл2\n");//выполняем какие то действия

        fl = 1;
    }
    if ((!strcmp(data1, data)) && (fl == 1)) // Вот этот блок всегда будет выполняться вместе с первым
    {
        printf("\nцикл3\n");

    }
    if ((strcmp(data1, data)) && (fl == 1)) // Сравниваем текст, а не указатели
    {
        printf("\nцикл4\n");
        strcpy(data1, data);
        fl = 0;
    }
    //    printf ("\nДата - %s",data);//когда дата меняется по идее data1 должна остаться старой, но получается что она равна data хотя никаких присваиваний я не делаю
    //    printf ("\nДата - %s",data1);
    //                printf ("\nфлаг - %d",fl);
}

int main()
{
    char Data[500] = "Test";

    strcpy(Data, "Test");
    OutXML(Data);

    strcpy(Data, "T2");
    OutXML(Data);
    strcpy(Data, "Test");
    OutXML(Data);
    OutXML(Data);
    return 0;
}


Код избавляющий от ошибки выполнения двух блоков примерно такой:

Код

//============================================================================
// Name        : test.cpp
// Author      : rodnover
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

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

static void OutXML(char* data)
{
    static char data1[1000]; //Указываем область, которой точно хватит
    static bool fl = 0;
    //                printf ("\nДата - %s",data);//когда дата меняется по идее data1 должна остаться старой, но получается что она равна data хотя никаких присваиваний я не делаю
    //        printf ("\nДата - %s",data1);
    //        printf ("\nфлаг - %d",fl);

    if ((strcmp(data1, data)) && (fl == 0))
    { // Сравниваем текст, а не указатели
        printf("\nцикл1\n");//выполняем какие то действия
        strcpy(data1, data); // Копируем сам текст, а не указатель
        fl = 1;
    } else if ((!strcmp(data1, data)) && (fl == 0))
    { // Сравниваем текст, а не указатели
        printf("\nцикл2\n");//выполняем какие то действия

        fl = 1;
    } else if ((!strcmp(data1, data)) && (fl == 1)) // Сравниваем текст, а не указатели
    {
        printf("\nцикл3\n");

    } else if ((strcmp(data1, data)) && (fl == 1)) // Сравниваем текст, а не указатели
    {
        printf("\nцикл4\n");
        strcpy(data1, data);
        fl = 0;
    }
    //    printf ("\nДата - %s",data);//когда дата меняется по идее data1 должна остаться старой, но получается что она равна data хотя никаких присваиваний я не делаю
    //    printf ("\nДата - %s",data1);
    //                printf ("\nфлаг - %d",fl);
}

int main()
{
    char Data[500] = "Test";

    strcpy(Data, "Test");
    OutXML(Data);

    strcpy(Data, "T2");
    OutXML(Data);
    strcpy(Data, "Test");
    OutXML(Data);
    OutXML(Data);
    return 0;
}


P.S.  в коде выше на пару сообщений, я, оказывается, лишнюю фигурную скобочку поставил. извиняюсь. smile

P.P.S. Если С++, то соглашусь, что лучше использовать стандартные стринги.

Автор: olegarh 8.9.2011, 14:00
так у тебя в коде char а у меня char*  с которым не работает

Автор: olegarh 8.9.2011, 15:09
Цитата(Леопольд @  8.9.2011,  07:37 Найти цитируемый пост)
 std::string.


Сделал так) все работает короче)
всем спасибо

Автор: rodnover 8.9.2011, 19:09
Цитата(olegarh @  8.9.2011,  18:00 Найти цитируемый пост)
так у тебя в коде char а у меня char*  с которым не работает

В этом у тебя и ошибка размер char * = 4 байта (для 32 битной системы). Содержит АДРЕС в памяти на строку. Он не копирует строку, он сохраняет в data1 адрес строки data. Когда ты меняешь строку в data - адрес не меняется, а значит data1 указывает на текст, который ты уже изменил. Вот и всё.  Со string, конечно, работает (и это лучший вариант), потому что он сохраняет не адрес, а последовательность символов.

Совет:
Разбирайтесь в С++ и указателях.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)