[ C / C++ ] — начинающим: задаем вопросы (архивная - 2015)

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by _Great_, 26 May 2007.

Thread Status:
Not open for further replies.
  1. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    По-моему ты сейчас не совсем понял то, что сам написал... Если на сайте что-то изменится, то код придется менять в любом случае. И ничего не мешает добавить необязательный параметр max_length в мой код, который будет говорить о том, сколько макимум символов копировать, если тебя это так волнует. А вот в твоем случае, если имя пользователя длиннее твоего буфера, то будет фейл опять-таки.

    Можно всегда поиграться с шаблонами и получить хороший результат.
    PHP:
    template<typename STRtypename Ttypename T2>
    STR substr_between(const STRstr, const Tdelim1, const T2delim2unsigned int max_length = -1)
    {
        
    STR ret;
        
    std::string::size_type pospos2;
        const 
    STRdelim1_ delim1;

        if((
    pos str.find(delim1_)) != std::string::npos &&
            (
    pos2 str.find(delim2pos)) != std::string::npos)
        {
            
    pos += delim1_.length();
            
    pos2 -= pos;
            
    ret.assign(strpospos2 max_length max_length pos2);
        }

        return 
    ret;
    }

    void main()
    {
        const 
    std::string str("hello my dear friend Max, How are you?");

        
    //Функция со строкой, первым и вторым разделителями const char*.
        
    std::cout << substr_between(str"friend "",") << std::endl;

        
    //То же, но второй разделитель char
        
    std::cout << substr_between(str"friend "',') << std::endl;

        
    //Еще вариант, но тут мы указали максимальную длину имени - 2 символа
        
    std::cout << substr_between(str"friend "","2) << std::endl;

        
    //Вариант, где все аргументы - const char*
        
    std::cout << substr_between<std::string>("hello my dear friend Max, How are you?""friend "",") << std::endl;

        const 
    std::wstring str2(L"hello my dear friend Max, How are you?");
        const 
    std::wstring delim1(L"friend "), delim2(L",");

        
    //та же функция с юникодовой строкой и юникодовыми разделителями в виде std::wstring
        
    std::wcout << substr_between(str2delim1delim2) << std::endl;
    }
    Кода меньше чем у тебя в твоей функции (если учесть, что она использует еще одну), а делает она больше и более универсальна. И этот алгоритм можно было еще получше обобщить, он еще не идеален, я просто не хочу тратить время.
    Сколько придется написать тебе, чтобы твои функции поддерживали хотя бы то же самое, что поддерживает моя?
     
    #5861 GRRRL Power, 27 Nov 2010
    Last edited: 27 Nov 2010
  2. rudi

    rudi Active Member

    Joined:
    3 Jun 2010
    Messages:
    492
    Likes Received:
    187
    Reputations:
    5
    GRRRL Power

    почитал я про щаблоны тут
    http://valera.asf.ru/cpp/book/c16.shtml

    Тема сильная конечно
    и очень сложная
     
  3. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Есть целая книжка по шаблонам С++ на полтысячи страниц (так и называется, "Шаблоны C++"), там действительно весьма сложные вещи затрагиваются, но для создания просто шаблонных функций знать нужно не так много. Для создания шаблонов классов с шаблонными методами - уже побольше)
    Для изучения возможностей C++ сначала достаточно почитать про ООП, что оно из себя в C++ представляет, про исключения, наследование, про классы, которые есть в stl и т.д.
     
    #5863 GRRRL Power, 28 Nov 2010
    Last edited: 28 Nov 2010
  4. Dimon32

    Dimon32 New Member

    Joined:
    6 May 2010
    Messages:
    55
    Likes Received:
    0
    Reputations:
    0
    Кто нибудь писал программу, которая считает сколько раз слово hello! написано в файле?
    (Слово необязательно написано на разных строчках)
     
  5. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Если по-простому, не учитывая, что "hello!" должно как-то быть отделено от текста, то так:

    PHP:
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <iterator>

    void main()
    {
        
    std::ifstream file;
        
    file.open("file.txt"std::ifstream::in);

        if(!
    file)
        {
            
    std::cout << "Error opening file" << std::endl;
            return;
        }

        
    std::string buf;

        
    std::copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(buf));

        
    file.close();

        
    std::string::size_type pos 0;
        
    unsigned int count 0;

        while((
    pos buf.find("hello!"pos)) != std::string::npos)
        {
            
    count++;
            
    pos++;
        }

        
    std::cout << "\"hello!\" found " << count << " time(s)." << std::endl;
    }
     
  6. return

    return New Member

    Joined:
    23 Oct 2010
    Messages:
    125
    Likes Received:
    3
    Reputations:
    1
    Нужно с mathcad'a вытянуть данные в массив и отсортировать. Данные вытягиваются как с обычного текстового файла? или же существуют какие то специальные функции для mathcad'a?
    З.Ы. С++
     
  7. cupper

    cupper Elder - Старейшина

    Joined:
    6 Jun 2007
    Messages:
    369
    Likes Received:
    92
    Reputations:
    5
    совсем плох я стал, совсем мозг зачерствел.
    Проблема есть метод которые тянет все записи из определенной таблицы БД. Не как не могу решиться как лучше их возвращать из метода. Пока наваял сей ужас
    Code:
    std::vector<Persone>* PersoneDB::GetAllPersone()
    {
    	sql::Driver* driver = get_driver_instance();
    	std::auto_ptr<sql::Connection> con(driver->connect(
        	DatabaseHelper::GetHelper().GetAddress(),
        	DatabaseHelper::GetHelper().GetUser(),
        	DatabaseHelper::GetHelper().GetPwd()
    		));
        con->setSchema(DatabaseHelper::GetHelper().GetDBname());
        std::auto_ptr<sql::Statement> stmt(con->createStatement());
        std::auto_ptr<sql::ResultSet> res(stmt->executeQuery(QueryAllPerson));
        std::vector<Persone>* persones = new std::vector<Persone>(res->rowsCount());
        while(res->next())
        {
        	Persone p(res->getInt("id"), res->getString("first_name"),
        		res->getString("last_name"), res->getString("birthday"));
        	(*persones)[res->getRow() - 1] = p;
        }
        return persones;	
    }
    
    Соответственно почему ужас ? для того что бы поместить значение в вектор нужно его создать, а потом еще и скопировать. Ужас ? Ужас! Хранить в векторе указатели конечно гуманней с точки зрения производительности, но совсем не гуманно с точки зрения последующего использования.
    Да и с самим вектором работать как с массивом становиться совсем не удобно (*persones)[].

    Мб правильней передавать в метод ссылку на вектор ?...
     
  8. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    cupper, даже 6я студия умеет оптимизировать код вот таким вот образом:
    PHP:
    std::vector<что-тоfunc()
    {
      
    std::vector<что-тоvector;

      
    //далее - любые действия с вектором, добавление в него инфы

      
    return vector;
    }

    void main()
    {
      
    std::vector<что-тоvec func(); //Копирования не происходит
    }
    Эта оптимизация в стандарте есть. Главное, чтобы во всех точках возврата из функции здесь возвращался один и тот же вектор.


    Второй вариант - возвращать std::auto_ptr с указателем на вектор внутри:
    PHP:
    std::auto_ptr<std::vector<что-то>> func()
    {
      
    std::auto_ptr<std::vector<что-то>> ptr(new std::vector<что-то>());

      
    //...

      
    return ptr;
    }

    void main()
    {
      
    std::auto_ptr<std::vector<что-то>> ptr func();
      
    //работаем с ptr, потом он сам все удалит
    }
    Ну и третий вариант - да, передавать в функцию ссылку на вектор. Лично я советовал бы использовать 1 или 3 вариант.

    А твой вариант плох еще тем, что если где-то внутри цикла while что-то бросит исключение, вектор, который ты создал с помощью new, никогда не удалится. Все перечисленные мной варианты такой вариант развития событий учитывают)
     
    #5868 GRRRL Power, 28 Nov 2010
    Last edited: 28 Nov 2010
  9. cupper

    cupper Elder - Старейшина

    Joined:
    6 Jun 2007
    Messages:
    369
    Likes Received:
    92
    Reputations:
    5
    эээто как так... локальная переменная после выхода из облсти дейтсвия не уничтожается О_о. Ни в одной из книг, да и вообще не когда об таком не слыхал. Какая то сомнительная оптимизация, а если я не буду принимать значение из функции, тогда удаляется ? А если и не вектор вовсе буду использовать, и вообще не stl типы (контейнеры)?

    Каждый твой пост для меня как открытие.
     
  10. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Поздравляю, ты только начинаешь изучать C++ )

    Во-первых, я тут возвращаю не ссылку, а сам объект, т.е. формально он должен скопироваться при выходе из функции (а ну удалиться, как ты написал. Такое произошло бы при возврате ссылки). Но оптимизатор по стандарту вектор, объявленный внутри функции, который мы возвращаем, выносит за ее пределы, поэтому копирования не производится. Единственное требование к тому, чтобы такая оптимизация была возможна - возвращать во всех точках выхода из функции один и тот же вектор (я уже писал об этом).

    Если ты не примешь значение, то объект просто умрет внутри функции, и ничего страшного не произойдет.

    Если ты мне не веришь про оптимизацию - создай класс с копирующим конструктором, который будет выводить нечто вроде "Я СКОПИРОВАН БЛЕАТЬ", потом сделай подобную функцию и вызови ее, как я показал. Собери release-билд и убедись, что он не вызывается. А лучше читай книжки, про это написано. Это стандарт.

    Используй на здоровье, хоть структуры используй, что угодно можно так возвращать.

    Вот, сделал тебе proof-пример:
    PHP:
    #include <iostream>

    class lol
    {
    public:
        
    explicit lol(unsigned int i)
            :
    i_(i)
        {}

        
    lol(const lolobj//копирующий конструктор подскажет нам, если что не так
        
    {
            
    i_ obj.i_;
            
    std::cout << "FFFUUUUU!" << std::endl;
        }

        
    void num_out() const
        {
            
    std::cout << i_ << std::endl;
        }

        
    void num_plus_plus()
        {
            
    i_++;
        }

    private:
        
    unsigned int i_;
    };

    lol function(unsigned int num)
    {
        
    lol obj(num);
        
    obj.num_plus_plus();
        return 
    obj;
    }


    void main()
    {
        
    lol test = function(5); //думаешь, тут есть копирование?
        //Ошибаешься. Его нет, билдь в release-сборку
        
    test.num_out();
    }
     
    #5870 GRRRL Power, 28 Nov 2010
    Last edited: 29 Nov 2010
  11. cupper

    cupper Elder - Старейшина

    Joined:
    6 Jun 2007
    Messages:
    369
    Likes Received:
    92
    Reputations:
    5
    пардон, сглупил. Но так не менее открытие для меня :)

    кроме стандарта в какой литературе данные финты описываются ? Для развития почитать.
     
  12. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    Есть древняя книга такая, "Язык программирования C++. Вводный курс", авторы Стенли Б. Липпман, Жози Лажойе. В ней вот описывается)
    Еще советую Скотта Мейерса почитать, "Наиболее эффективное использование C++".
     
    #5872 GRRRL Power, 29 Nov 2010
    Last edited: 29 Nov 2010
  13. shake shake

    shake shake New Member

    Joined:
    22 Nov 2010
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    Помогите нубу пжалста...
    выдает вот такое вот

    "Задание 2.exe": Загружено: "C:\Users\Павло\Documents\Visual Studio 2010\Projects\Задание 2\Debug\Задание 2.exe", Символы загружены.
    "Задание 2.exe": Загружено: "C:\Windows\System32\ntdll.dll", Невозможно найти или открыть файл PDB
    "Задание 2.exe": Загружено: "C:\Windows\System32\kernel32.dll", Невозможно найти или открыть файл PDB
    "Задание 2.exe": Загружено: "C:\Windows\System32\msvcr100d.dll", Символы загружены.
    Программа "[26416] Задание 2.exe: Машинный код" завершилась с кодом 0 (0x0).


    когда компилирую вот это

    #include <windows.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glaux.h>


    void CALLBACK resize( int width, int height );
    void CALLBACK display( void );







    void main()
    {

    auxInitDisplayMode( AUX_RGBA | AUX_DEPTH | AUX_DOUBLE );

    auxInitPosition( 50, 10, 800, 800);
    auxInitWindow( "Программа 1.1");



    auxReshapeFunc( resize );

    glEnable( GL_ALPHA_TEST );
    glEnable( GL_DEPTH_TEST );
    glEnable( GL_COLOR_MATERIAL );

    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glEnable( GL_LIGHTING );
    glEnable( GL_LIGHT0 );

    float pos[4] = { 3, 3, 3, 1 };
    float dir[3] = { -1, -1, -1 };
    glLightfv( GL_LIGHT0, GL_POSITION, pos );
    glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, dir );
    auxMainLoop( display );
    }

    void CALLBACK resize( int width,int height )
    {
    glViewport( 0, 0, width, height );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    glOrtho( -5, 5, -5, 5, 2, 12);

    gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
    glMatrixMode( GL_MODELVIEW );
    }

    void CALLBACK display(void)
    {
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glLoadIdentity();

    glColor3d( 1, 1, 0 );
    glTranslated(-4,4,0);
    auxSolidTorus( 0.2, 0.5);

    glTranslated( 2, 0, 0 );
    auxSolidCube( 1 );

    glTranslated(3, -2, 0);
    auxSolidBox(1, 1, 1);

    glTranslated(0, 1, 0);
    auxSolidCylinder(1, 0.5);

    glTranslated(-7, -1.5, 0);
    auxSolidCone(1, 0.5);

    glTranslated(2, 0, 0);
    auxSolidIcosahedron( 1 );

    glTranslated(1, -2, 0);
    auxSolidOctahedron(0.6);

    glTranslated(-3, 0, 0);
    auxSolidTetrahedron(0.7);

    glTranslated(1.5, -1.5, 0);
    auxSolidDodecahedron(0.8);

    glTranslated(4, 0, 0);
    auxSolidTeapot(0.8);


    auxSwapBuffers();
    }

    ЧТО это вообще такое?Нету библиотеки?
     
  14. B@ton

    B@ton New Member

    Joined:
    18 Jul 2007
    Messages:
    17
    Likes Received:
    1
    Reputations:
    0
    Почему после использования cin.get() перестает работать вывод вне цикла??
    Code:
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    
    int main()
    { 
    	int column=0;
    	int str=0;
    	int i=0;
    	int j=0;
    	const int N=5;
    char tableTris [N][N];
    char tempArray[25];
    for(i=0; i<25; i++)
    {
    	
    	tempArray[i]=cin.get();
    cout << i;
    	
    }
    
    for(j=0; j<25; j++)
    {
    \\ тут уже не выводит
    	cout<<tempArray[j];
    }
    
    
    }
    
     
  15. Edward

    Edward Banned

    Joined:
    11 Feb 2010
    Messages:
    329
    Likes Received:
    21
    Reputations:
    -1
    После
    Code:
    tempArray[i] = cin.get();
    добавьте

    Code:
    cin.ignore();
    И все будет в порядке.

    И научитесь по человечески код оформлять, а то аж читать противно.

    Code:
    #include <iostream>
    
    int main( int argc, char *argv[] ) { 
    	char tempArray[ 25 ];
    
    	for( int i = 0; i < 25; i++ ) {
    		tempArray[ i ] = std::cin.get();
    		std::cin.ignore();
    		std::cout << "-----" << i << "-----" << std::endl;
    	}
    
    	for( int k = 0; k < 25; k++ ) {
    		std::cout << tempArray[ k ];
    	}
    	return 0;
    }
     
    #5875 Edward, 29 Nov 2010
    Last edited: 29 Nov 2010
  16. B@ton

    B@ton New Member

    Joined:
    18 Jul 2007
    Messages:
    17
    Likes Received:
    1
    Reputations:
    0
    cin.ignore() уже вставлял он не дает ни какого результата! Во втором цикле вывод не происходит, продолжается считывание cin.get().
     
  17. rudi

    rudi Active Member

    Joined:
    3 Jun 2010
    Messages:
    492
    Likes Received:
    187
    Reputations:
    5

    измени код немного так, так более наглядней.
    И когда запускаешь программу, вводи сразу 25 символов
    и потом жми Enter. все сработает.
    В твоем случае ты должен ввести сразу 25 символов а потом нажать интер
    потому что вводя данные с клавиатуры, они попадают в некий системный буфер, а нажав интер или пробел ты передаешь данные на обработку функцией cin.get();
    И если ты ввел не 25 а например 20 символов,
    то цикл не прекратиться, так как он ожидает прием 25 символов.


    PHP:
    int main(int argccharargv[])
    {
        
    int column=0;
        
    int str=0;
        
    int i=0;
        
    int j=0;
        const 
    int N=5;
        
    char tableTris [N][N];
        
    char tempArray[25];
        for(
    i=0i<25i++)
        {        
            
    tempArray[i]=cin.get();
            
    cout << << " - " << tempArray[i] << endl;    
        }
        
    cout << endl;

        for(
    j=0j<25j++)
        {
            
    // тут уже  выводит
            
    cout<<tempArray[j] << endl;
        }


        return 
    0;
    }
    Но как вариант , можно переписать твой код
    используя функцию getche
    она сразу выводит Эхо введенного символа не ожидая от тебя когда ты заполнишь системный буфер и передаш на обработку своей функции cin.get()
    В этом случае getche() сразу передает введеный тобою символ в твой цыкл

    PHP:

    #include <iostream>
    #include <string>
    #include <conio.h>
    using namespace std;

    int main(int argccharargv[])
    {
        
    int column=0;
        
    int str=0;
        
    int i=0;
        
    int j=0;
        const 
    int N=5;
        
    char tableTris [N][N];
        
    char tempArray[25];
        for(
    i=0i<25i++)
        {        
                       
    cout << << " - ";
            
    tempArray[i]= getche();
            
    cout << endl;
        }
        
    cout << endl;

        for(
    j=0j<25j++)
        {
            
    // тут уже  выводит
            
    cout<<tempArray[j];
        }
        
    cout << endl

        return 
    0;
    }

     
    #5877 rudi, 30 Nov 2010
    Last edited: 30 Nov 2010
    1 person likes this.
  18. Pack4

    Pack4 New Member

    Joined:
    28 Jun 2010
    Messages:
    10
    Likes Received:
    0
    Reputations:
    0
    vector.h

    Привет всем. Помогите пожалуйста разобраться с классом vector.h))))
    Вот написал такой код cout выдает ошибку:
    Code:
    #include <iostream.h> 
    #include <vector.h>
      void main(int x, int y)
     { 
    pair <int,int> absc(x,y);
     vector <pair <int,int> > v; 
     cout<<"Vvedite paru x,y: \n"; 
    cin>>x>>y; 
    v.push_back(absc); 
     vector < pair <int,int> >::iterator h; 
    for(h=v.begin(); h<v.end(); h++) 
    cout << *h<< endl; 
    char t[10]; 
    cin>>t;  
    } 
    
    Суть такова, в vector должны записываться значения попарно, x и y
    Так же можно было бы выбрать определенную пару по индексу, и удалить, или перезаписать, как я понял для этого нужен итератор.
    Как дальше сделать :confused:
     
  19. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    "Вектор пар" - это уже готовый контейнер multimap)
     
  20. Pack4

    Pack4 New Member

    Joined:
    28 Jun 2010
    Messages:
    10
    Likes Received:
    0
    Reputations:
    0
    Ну а если все же через вектор, плииииз помогите!))))
    Просто map и multimap характеризуются как словари и словари с дубликатами. А для значений пары координат мне кажется грамотнее будет использовать все же vector
     
    #5880 Pack4, 30 Nov 2010
    Last edited: 30 Nov 2010
Thread Status:
Not open for further replies.