DeadManWalking Skrevet 12. november 2007 Del Skrevet 12. november 2007 Den koden fungerer vel ikke på æøå? Lenke til kommentar
Steinbitglis Skrevet 29. august 2008 Del Skrevet 29. august 2008 Mange lurer på hvordan du sorterer strenger med norske regler (aa etter z osv.) Her er en enkel sak som bruker std::locale som et funksjonsobjekt til å sortere en std::vector bestående av strenger. #include <string> #include <locale> #include <vector> #include <algorithm> int main(int argc, char *argv[]) { // vi bruker en vector med strenger std::vector<std::string> v; // legger til strenger i vectoren v.push_back("Aabel, Per"); v.push_back("Zappa, Frank"); v.push_back("Young, Neil"); v.push_back("A Perfect Circle"); v.push_back("Mazzy Star"); v.push_back("Harvey, PJ"); v.push_back("Portishead"); v.push_back("Aaliyah"); v.push_back("Amos, Tori"); v.push_back("Aarset, Eivind"); v.push_back("Tool"); // bruker std::sort i algorithm for å sortere std::sort(v.begin(), v.end(), std::locale("") ); } Merk at std::locale c'toren vi bruker tar en streng som argument. Det er forskjell på å skrive std::locale() og std::locale("")! Den første varianten bruker "C" locale, mens den andre velger brukerens ønskede locale (i Windows vil det som regel si brukerens regioninstilling). Fordelen med dette er at koden også vil fungere for brukere med andre regioninstillinger (f.eks. svensker, tyskere....). Hvis du ønsker å hardkode strengen til å bruke norske regler, kan du prøve å skrive inn "no" istedenfor en blank streng, slik: std::sort(v.begin(), v.end(), std::locale("no") ); locale strengene er forøvrig ikke spesifisert i C++ standarden og kan være implementasjonsavhengig. Men jeg vil tro at "no" vil fungere de fleste steder Jeg trodde kanskje dette kune ordne til at lister ble sortert korrekt med tanke på æøå, men det gjorde det ikke med mingw i alle fall. æøå fungerte til min store overraskelse mellom kildekode og konsollvinduet, men ikke til sorteringa altså. Det er dog litt mistenkelig at programmet krasjer hvis jeg hadkoder locale 'nb-NO' eller 'no', eller 'french' for den saks skyld Lenke til kommentar
South_Bridge Skrevet 15. november 2008 Del Skrevet 15. november 2008 Edit at ID3Tagger (taggene: album, artist og navn+++ i MP3) Kanskje litt silly, men jeg synes kanskje tutorial til id3lib var litt avskrekkende. Så om du er newb men har lyst til å fikle med id3 taggene i feks en mp3 fil så legger jeg ved følgende kode som gir deg en god kickstart! LINK: id3lib #include <id3/tag.h> ID3_Tag myTag; myTag.Link(url_til_mp3_fil); ID3_Frame* albumFrame = myTag.Find(ID3FID_ALBUM); albumField = albumFrame->GetField(ID3FN_TEXT); albumField->Set("navn_som_settes_inn_i_album_på_gjeldene_mp3fil"); myTag.Update(); Lenke til kommentar
LostOblivion Skrevet 2. desember 2008 Del Skrevet 2. desember 2008 (endret) Trimming av C string Trimmer av whitespace i starten og slutten av en C string. #include <string.h> #include <ctype.h> char *strtrm(char *str) { int from, to, i; from = 0; while (str[from] && isspace(str[from])) from++; to = strlen(str)-1; while (to >= 0 && isspace(str[to])) to--; i = 0; while (from <= to) str[i++] = str[from++]; str[i] = 0; return str; } Endret 2. desember 2008 av LostOblivion Lenke til kommentar
Tapped Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Her er en kode-snutt som kan brukes til finne ut hvor mange sekunder det har gått fra en tid til en annen. Programmet funker bare i Windows fordi jeg bruker get-ticks funksjonen, men kan lett implementeres til Linux eller Mac. Ideen fikk jeg av Lazy Foo, men jeg har skrevet min egen lignende kode. Jeg var tretten år gammel når jeg lagde denne koden. Jeg bruker den mest til spill, som å regulere fps(framespersecond). Her er header filen: /* Made by Emil Sandstø 2009 */ #ifndef TIME #define TIME #include "Windows.h" class Timer { private: DWORD startTicks; int pausedTicks; bool paused; bool started; public: Timer(); void start();//Starter klokken. void stop();//Stopper klokken. void pause();//Pauser klokken. void unpause();//Fortsetter fra klokken pauset. DWORD get_ticks();//Sender deg tiden som klokken har tikket fra den startet i millisekunder. bool is_started(); bool is_paused(); }; #endif Her er cpp filen: /* Made by Emil Sandstø 2009 */ #include "Windows.h" #include "Time.h" Timer::Timer() { startTicks = 0; pausedTicks = 0; paused = false; started = false; } void Timer::start() { started = true; paused = false; startTicks = GetTickCount(); } void Timer::stop() { started = false; paused = false; } DWORD Timer::get_ticks() { if ( started == true ) { if ( paused == true ) { return pausedTicks; } else { return GetTickCount() - startTicks; } } return 0; } void Timer::pause() { if (( started == true ) && ( paused == false )) { paused = true; pausedTicks = GetTickCount() - startTicks; } } void Timer::unpause() { if ( paused == true ) { paused = false; startTicks = GetTickCount() - pausedTicks; pausedTicks = 0; } } bool Timer::is_started() { return started; } bool Timer::is_paused() { return paused; } Lenke til kommentar
GeirGrusom Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Hvis du først skal gjøre det Windows spesifikt burde du bruke QueryPerformanceFrequency og QueryPerformanceCounter. Disse teller antall instruksjoner prosesoren har utført og er så presise du får det. Lenke til kommentar
Bytex Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 (endret) Hvor vanlig er det å bruke "using namespace std" istedet for å skrive std:: foran alle kommandoer som er i std? Ser folk bruker begge deler. Er jo lettere å skriver cout enn std::cout tross alt? Endret 4. februar 2010 av Bytex Lenke til kommentar
GeirGrusom Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Det er greit å bruke fulle namespace i .h filer. Men ja. Lenke til kommentar
Bytex Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 (endret) Jeg bare tenker, i Accellerated C++ boka er aldri "using namespace std" med, så han kjører på med string:: og cout:: og alle mulige andre kommandoer med :: foran, istedet for å bare definere hvilken namespace kommandoene er i fra starten av og slipper å skrive std:: foran alt 30 ganger nedover..hvorfor gjør han det? Når jeg skriver inn eksempelprogrammene slenger jeg bare inn using namespace std og using namespace string istedet for å skrive masse ekstra hele tiden. Det funker jo likevel. Den boka er glimrende forresten, man lærer litt "kule ting" helt i starten istedet for å bli druknet i OO teori. F.eks. er en av de første programsnuttene hvordan man lager en *********** border rundt en tekst, der programmeret genererer borderen etter hvor mange bokstaver man har. Så den blir alltid riktig uansett hvor lang setning man skriver inn Endret 4. februar 2010 av Bytex Lenke til kommentar
NevroMance Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Problemet med å bruke using namespace * i en .h fil, er hvis f. eks. iostream blir inkludert i en cpp fil, som også inkluderer denne .h filen. Hvis du da i .cpp filen bruker std::cout får du konflikter, siden du allerede har sagt at du bruker namespacet. Lenke til kommentar
GeirGrusom Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Jeg bare tenker, i Accellerated C++ boka er aldri "using namespace std" med, så han kjører på med string:: og cout:: og alle mulige andre kommandoer med :: foran, istedet for å bare definere hvilken namespace kommandoene er i fra starten av og slipper å skrive std:: foran alt 30 ganger nedover..hvorfor gjør han det? Det er en god idé at lærebøker er eksplisitte. I C++ er ikke namespaces så utbredt som det kunne vært, men noen prosjekter bruker det mye, og da kan det føre til forvirring dersom eksempelkode for eksempel utelatter hvilket namespace som er i bruk. Dette er noe som ofte irriterer meg i .NET sin dokumentasjon, altså at eksempelforfatteren har brukt noen using uten å fortelle hvilke. Lenke til kommentar
Bytex Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 (endret) Så det er egentlig en dårlig vane jeg legger meg til? Jeg bare gidder ikke skrive std:: 10 ganger nedover når det er et lite program som bare skriver ut ting i et console vindu. Her er snutten som lager ************** border rundt tekst du inputter, forresten. Syns det var et kult triks, og ikke så komplisert heller. #include <iostream> #include <string> int main() { std::cout << "Skriv fornavnet ditt her: "; std::string name; std::cin >> name; // bygge meldingen vi outputter const std::string greeting = "Hallo, " + name + "!"; // bygge 2. og 4. linje av border const std::string spaces(greeting.size(), ' '); const std::string second = "* " + spaces + " *"; // bygge 1. og 5. linje av border const std::string first(second.size(), '*'); // skrive ut alt sammen std::cout << std::endl; std::cout << first << std::endl; std::cout << second << std::endl; std::cout << "* " << greeting << " *" << std::endl; std::cout << second << std::endl; std::cout << first << std::endl: std::cin.get(); return 0; } Nå vil du få en perfekt * border rundt det du skriver som input. Som du ser blir det endel std:: istedet for å bruke using namespace std i starten Endret 4. februar 2010 av Bytex Lenke til kommentar
GeirGrusom Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Meh. Som NevroMance sier: ikke skriv using namespace i headerfiler. I .cpp filer er det ikke så farlig. Lenke til kommentar
Tapped Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 Hvis du først skal gjøre det Windows spesifikt burde du bruke QueryPerformanceFrequency og QueryPerformanceCounter. Disse teller antall instruksjoner prosesoren har utført og er så presise du får det. Det er sant at QueryPerformanceFrequency er mer nøyaktig enn Get-TickCount, men hvis du bruker dette for å kontrollere fps er det veldig lett å gjøre en speedhack som for eksempel overklokke cpu, og da går jo fps'en opp å det er ikke en bra når det gjelder spill. I tillegg funker ikke QueryPerformanceFrequency nøyaktig på alle CPU'er. Lenke til kommentar
GeirGrusom Skrevet 4. februar 2010 Del Skrevet 4. februar 2010 (endret) Hvis du først skal gjøre det Windows spesifikt burde du bruke QueryPerformanceFrequency og QueryPerformanceCounter. Disse teller antall instruksjoner prosesoren har utført og er så presise du får det. Det er sant at QueryPerformanceFrequency er mer nøyaktig enn Get-TickCount, men hvis du bruker dette for å kontrollere fps er det veldig lett å gjøre en speedhack som for eksempel overklokke cpu, og da går jo fps'en opp å det er ikke en bra når det gjelder spill. I tillegg funker ikke QueryPerformanceFrequency nøyaktig på alle CPU'er. Hvis du leser dokumentasjonen, ser du at dette ikke er tilfellet ^^ edit: at klokka i PC-en ikke er nøyaktig uansett, men du har helt rett, men High resolution timer er mer presis enn GetTickCount som kan ha en oppløsning på mellom 10 og 16 ms. Endret 5. februar 2010 av GeirGrusom Lenke til kommentar
TheMaister Skrevet 5. februar 2010 Del Skrevet 5. februar 2010 Funker ikke clock_gettime() bra, eller er dette en Unix only greie? Lenke til kommentar
GeirGrusom Skrevet 5. februar 2010 Del Skrevet 5. februar 2010 Funksjonen er ikke nevnt på msdn... Lenke til kommentar
Tapped Skrevet 4. mars 2010 Del Skrevet 4. mars 2010 (endret) Jeg har laget min egen slags Vector class. Den er ganske fiffig å ha i programmet sitt. Den kan brukes som arrays bare at du har mulighet til å resize arrayen. Jeg er 14 år gammel. Og har programmert i to år nå. Jeg lagde denne greia som en egen øvelse for templates og fordi jeg trenger det i spillene jeg lager. De smarte triksene har jeg fått av eksempler fra andre. Du burde lagre denne greia som en header fil og inkludere den i prosjektet ditt. #ifndef LINKEDLIST_H #define LINKEDLIST_H #include <stdlib.h> #include <stdio.h> #include <time.h> #define SAFE_DELETE( p ) { if ( p ) { delete ( p ); ( p ) = 0; } } //--------------------------------------------------------------------------- //Linked List Class //--------------------------------------------------------------------------- template< class Type > class LinkedList { public: //--------------------------------------------------------------------------- //Element Struct //--------------------------------------------------------------------------- struct Element { Type * data; Element * next; Element * prev; Element( Type * Element ) { data = Element; next = prev = NULL; } ~Element() { SAFE_DELETE( data ); if ( next ) next->prev = prev; if ( prev ) prev->next = next; } }; //--------------------------------------------------------------------------- //Linked List Constructor and Destructor //--------------------------------------------------------------------------- LinkedList() { m_first = m_last = m_iterate = m_temp = NULL; m_totalElements = 0; } ~LinkedList() { Empty(); } //--------------------------------------------------------------------------- //Add a new element to list //--------------------------------------------------------------------------- Type * Add( Type * element ) { if ( element == NULL ) return NULL; if ( m_first == NULL ) { m_first = new Element( element ); m_last = m_first; } else { m_last->next = new Element( element ); m_last->next->prev = m_last; m_last = m_last->next; } ++m_totalElements; return m_last->data; } //--------------------------------------------------------------------------- //Insert a element before the next element //--------------------------------------------------------------------------- Type * InsertBefore( Type * element, Element * nextElement ) { m_temp = nextElement->prev; ++m_totalElements; if ( m_temp = NULL ) { m_first = new Element( element ); m_first->next = nextElement; nextElement->prev = m_first; return m_first->data; } else { nextElement->prev = new Element( element ); m_temp->next = nextElement->prev; nextElement->prev->next = nextElement; nextElement->prev->prev = m_temp; return m_temp->next->data; } } //--------------------------------------------------------------------------- //Removing a element //--------------------------------------------------------------------------- Type * Remove( Type * *element ) { m_temp = m_first; while ( m_temp != NULL ) { if ( m_temp->data == element ) { if ( m_temp = m_first ) { m_first = m_first->next; if ( m_first ) m_first->prev = NULL; } if ( m_temp = m_last ) { m_last = m_last->prev; if ( m_last ) m_last->next = NULL; } SAFE_DELETE( m_temp ); *element = NULL; --m_totalElements; return; } m_temp = m_temp->next; } } //--------------------------------------------------------------------------- //Destroys every element in the list and deleting the data //--------------------------------------------------------------------------- void Empty() { while ( m_last != NULL ) { m_temp = m_last; m_last = m_last->prev; SAFE_DELETE( m_temp ); } m_first = m_last = m_temp = m_iterate = NULL; m_totalElements = 0; } //------------------------------------------------------------------------- // Removes all the elements and clears their data pointers. //------------------------------------------------------------------------- void ClearPointers() { while( m_last != NULL ) { m_temp = m_last; m_temp->data = NULL; m_last = m_last->prev; SAFE_DELETE( m_temp ); } m_first = m_last = m_iterate = m_temp = NULL; m_totalElements = 0; } //------------------------------------------------------------------------- // Removes the given element and clears its data pointer. //------------------------------------------------------------------------- void ClearPointer( Type **element ) { m_temp = m_first; while( m_temp != NULL ) { if( m_temp->data == *element ) { if( m_temp == m_first ) { m_first = m_first->next; if( m_first ) m_first->prev = NULL; } if( m_temp == m_last ) { m_last = m_last->prev; if( m_last ) m_last->next = NULL; } m_temp->data = NULL; SAFE_DELETE( m_temp ); *element = NULL; m_totalElements--; return; } m_temp = m_temp->next; } } //------------------------------------------------------------------------- // Iterates through the elements in the linked list. //------------------------------------------------------------------------- Type *Iterate( bool restart = false ) { if( restart ) m_iterate = NULL; else { if( m_iterate == NULL ) m_iterate = m_first; else m_iterate = m_iterate->next; } if( m_iterate == NULL ) return NULL; else return m_iterate->data; } //------------------------------------------------------------------------- // Returns the currently iterated element in the linked list. //------------------------------------------------------------------------- Type *GetCurrent() { if( m_iterate ) return m_iterate->data; else return NULL; } //------------------------------------------------------------------------- // Returns the first element in the linked list. //------------------------------------------------------------------------- Type *GetFirst() { if( m_first ) return m_first->data; else return NULL; } //------------------------------------------------------------------------- // Returns the last element in the linked list. //------------------------------------------------------------------------- Type *GetLast() { if( m_last ) return m_last->data; else return NULL; } //------------------------------------------------------------------------- // Returns the next element in the linked list from the given element. //------------------------------------------------------------------------- Type *GetNext( Type *element ) { m_temp = m_first; while( m_temp != NULL ) { if( m_temp->data == element ) { if( m_temp->next == NULL ) return NULL; else return m_temp->next->data; } m_temp = m_temp->next; } return NULL; } //------------------------------------------------------------------------- // Returns a random element from the linked list. //------------------------------------------------------------------------- Type *GetRandom() { if( m_totalElements == 0 ) return NULL; else if( m_totalElements == 1 ) return m_first->data; unsigned long element = rand() * m_totalElements / RAND_MAX; m_temp = m_first; for( unsigned long e = 0; e < element; e++ ) m_temp = m_temp->next; return m_temp->data; } //------------------------------------------------------------------------- // Returns the complete element (including its next and previous pointers). //------------------------------------------------------------------------- Element *GetCompleteElement( Type *element ) { m_temp = m_first; while( m_temp != NULL ) { if( m_temp->data == element ) return m_temp; m_temp = m_temp->next; } return NULL; } //------------------------------------------------------------------------- // Returns the total number of elements in the linked list. //------------------------------------------------------------------------- unsigned long GetTotalElements() { return m_totalElements; } private: Element * m_last; Element * m_first; Element * m_iterate; Element * m_temp; unsigned long m_totalElements; }; #endif Her er et eksempel på hvordan du bruker den. Jeg kaller header filen som inneholder LinkedList classen for "LinkedList.h" #include <LinkedList.h> #include <iostream> int main() { int a = 0; int b = 0; int *pC = 0; //Lager en pointer som peker til NULL int d = 0; pC = (int*)200; //Pointer mot 200 LinkedList<int> tall; // Lager en liste <int> liste tall.Add( (int*) 50 ); // Setter inn en pointer til 50 i listen tall.Add( pC ); // Setter inn pointer i listen tall.Add( (int*) 80 ); //Setter inn en pointer til 80 i listen std::cout << "Iterater gjennom listen\n"; tall.Iterate( true ); while( tall.Iterate() ) { std::cout <<(int)tall.GetCurrent() << " " << std::endl; // Får tallet som //blir iterated } a = (int)tall.GetFirst(); // Får første tallet i listen b = (int)tall.GetLast(); // Får siste tallet i listen std::cout << "Får første og siste tall i listen.\n"; std::cout << a << " " << b; d = (int)tall.GetNext( pC ); std::cout << "\nFår neste etter andre elementet i listen som er 200\n"; std::cout << d; std::cin.get(); return 0; } Endret 5. mars 2010 av Tapped Lenke til kommentar
[kami] Skrevet 16. juni 2010 Del Skrevet 16. juni 2010 (endret) Jeg har laget min egen slags Vector class .. snip .. hvor nyttig er egentlig dette når vi har stl? Dette er helt basic stuff som man lærer 1 året i en programmeringsklasse. i tilegg mangler den standard ting som * iteratorer LinkedList<int> liste; sort(liste.begin(), liste.end() ); // dette vil ikke fungere. * er ikke const correct const Linkedlist<int> liste; liste.GetTotalElements()(); /// compiler error. burde ikke gi det, da dette kallet ikke modifiserer lista i det hele tatt. * må caste for å insette pod types. Linkedlist<int> liste: liste.Add(10); // funker ikke, må caste.. Dette er jo bare rot, jeg har jo allerede definert at typen jeg skal bruke er en int, ikke en int*! Du skriver også at den ligner på et array, men du har ikke laget [] operatorer til den. ta en titt på std::vector (som array - men kan resizes), std::list (vanlig linka liste), std::set (sortert), std::map (key, value oppslag) eneste som kunne vært nyttig her er en rask og minneeffektiv version av std::vector. de vanlige containerne som finnes i stl, har mer funksjonalitet og er bedere enn det du har laget her. Sorry, men skal det være kodesnutter her, bør det være noe folk har bruk for. Endret 16. juni 2010 av [kami] Lenke til kommentar
Jaffe Skrevet 4. september 2010 Del Skrevet 4. september 2010 Jeg har laget min egen slags Vector class. blabla Øh, den er jo kliss lik denne nesten. Ikke påstå at du har lagd ting du ikke har lagd... Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå