C++ Programming HOW-TO Al Dev (Alavoor Vasudevan) alavoor@yahoo.com v5.0, 4¿ù 9ÀÏ 2000 ±è ÁöÈñ, À± ÁÖö 2000³â 6¿ù 15ÀÏ ÀÌ ¹®¼­´Â C++ÀÇ ¸Þ¸ð¸® ¹®Á¦¸¦ ÇÇÇÏ´Â ¹æ¹ý¿¡ ´ëÇØ ´Ù·ç¸ç C++¾ð¾î¸¦ ¿Ã¹Ù¸£°Ô ÇÁ·Î±×·¥ ÇÒ¼ö ÀÖµµ·Ï µµ¿Í ÁÖ°íÀÚ ÇÑ´Ù. ÀÌ ¹®¼­ÀÇ Á¤º¸´Â ¸ðµç ¿î¿µÃ¼Á¦ - ¸®´ª½º, MS DOS, ¾ÖÇà ¸ÆŲÅä½Ã, À©µµ¿ì 95/NT, OS/2, IBM ¿î¿µÃ¼Á¦µé, VMS, Novell Netware, À¯´Ð½ºÀÇ ¸ðµç Á¾·ù (¼Ö¶ó¸®½º, HPUX, AIX, SCO, Sinix, BSCµî..), ±×¸®°í "C++" ÄÄÆÄÀÏ·¯¸¦ Áö¿øÇÏ´Â ¸ðµç ´Ù¸¥ ¿î¿µÃ¼Á¦µé (´Ù½Ã ¸»ÇØ ÀÌ Áö±¸»ó¿¡ Á¸ÀçÇÏ´Â °ÅÀÇ ¸ðµç ¿î¿µÃ¼Á¦µéÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù)- ¿¡ Àû¿ëµÉ¼ö ÀÖ´Ù. ______________________________________________________________________ ¸ñÂ÷ 1. ¼­·Ð 1.1 ÇöÀç C++ ÄÄÆÄÀÏ·¯µéÀÌ Á÷¸éÇÑ ¹®Á¦µé 1.2 "C" ¸¦ ¾µ°ÍÀΰ¡ "C++" À» ¾µ°ÍÀΰ¡ ¾Æ´Ï¸é ÀÚ¹Ù¸¦ ¾µ°ÍÀΰ¡? 2. ´Ù¿î·Îµå mychar AID CDATA Download mychar(LABEL)LABEL 3. mychar classÀÇ »ç¿ë 3.1 ¿¬»êÀÚµé 3.2 ÇÔ¼öµé 3.3 ±âŸ ÇÔ¼öµé 4. C++ Zap (Delete) ¸í·É¾î AID CDATA zap(LABEL)LABEL 5. my_malloc °ú my_freeÀÇ »ç¿ë AID CDATA my_malloc(LABEL)LABEL 6. Debug È­Àϵé 7. C++ Online ¹®¼­µé 7.1 C++ Æ©Å͸®¾óµé 7.2 C++ ÄÚµù Ç¥ÁØ 7.3 C++ Äü ·¹ÆÛ·±½º 7.4 C++ À¯Áî³Ý ´º½º±×·ìµé 8. ¸Þ¸ð¸® µµ±¸µé 9. °ü·Ã URLµé 10. ÀÌ ¹®¼­ÀÇ ´Ù¸¥ Æ÷¸äµé 11. ÀúÀÛ±Ç 12. ÷ºÎ A example_mychar.cpp AID CDATA Appendix A(LABEL)LABEL 13. ÷ºÎ B mychar.h AID CDATA Appendix B(LABEL)LABEL 14. ÷ºÎ C mychar.cpp AID CDATA Appendix C(LABEL)LABEL 15. ÷ºÎ D my_malloc.cpp AID CDATA Appendix D(LABEL)LABEL 16. ÷ºÎ E my_malloc.h AID CDATA Appendix E(LABEL)LABEL 17. ÷ºÎ F debug.h AID CDATA Appendix F(LABEL)LABEL 18. ÷ºÎ G debug.cpp AID CDATA Appendix G(LABEL)LABEL 19. ÷ºÎ H Makefile AID CDATA Appendix H(LABEL)LABEL ______________________________________________________________________ 1. ¼­·Ð C++ Àº °¡Àå ³Î¸® ¾²ÀÌ´Â ¾ð¾îÀÌ°í, ¾ÕÀ¸·Ð ÀÚ¹ÙÀÇ µîÀå°ú´Â »ó°ü¾øÀÌ ¿À·£ ±â°£µ¿¾È ¾²ÀÏ °ÍÀÌ´Ù. C++ Àº ¸Å¿ì ºü¸£°Ô ½ÇÁ¦·Î ÀÚ¹Ùº¸´Ù 20³»Áö 30¹è ´õ »¡¸® ½ÇÇàµÈ´Ù. ÀÚ¹Ù´Â "virtual engine"À§¿¡¼­ ÀÛµ¿µÇ´Â ¹ø¿ª (interpreted)¾îÀ̱⶧¹®¿¡ ¸Å¿ì ´À¸®°Ô ½ÇÇàµÈ´Ù. ÀÚ¹Ù¿¡¼­ ¸Þ¸ð¸® °ü¸®´Â ÀÚµ¿ÀÌ¶ó¼­ ÇÁ·Î±×·¡¸ÓµéÀº ¸Þ¸ð¸® ¾ó·ÎÄÉÀÌ¼Ç (allocation) À» Á÷Á¢ ´Ù·çÁö ¾Ê´Â´Ù. ÀÌ ¹®¼­´Â C++ »ç¿ëÀ» ´õ¿í ÆíÇÏ°Ô Çϱâ À§ÇØ C++ ¿¡¼­ÀÇ ¸Þ¸ð¸® °ü¸®¸¦ ÀÚµ¿È­ÇÏ´Â °ÍÀ» ½ÃµµÇÑ´Ù. ÀÚ¹ÙÀÇ ÁÁÀº Á¡ ¸Þ¸ð¸® ¾ó·ÎÄÉÀ̼ÇÀÌ ÀÚµ¿ÀûÀ¸·Î 󸮵ȴٴ °ÍÀÌ´Ù. ÀÌ howto´Â "C++"ÀÌ ¸Þ¸ð¸® °ü¸®¸é¿¡¼­ ÀÚ¹Ù ¾ð¾î¿Í(¸¦) "°æÀï/¸ð¹æ"ÇÏ´Â °ÍÀ» °¡´ÉÇÏ°Ô ÇÒ °ÍÀÌ´Ù. C++ ÇÁ·Î±×·¡¸ÓµéÀº ¼öµ¿ ¸Þ¸ð¸® ¾ó·ÎÄÉÀ̼Ƕ§¹®¿¡ ¸¹Àº ½Ã°£À» ¼ÒºñÇÑ´Ù. ÀÌ ¹®¼­¿¡ ÀÖ´Â Á¤º¸´Â ¿©·¯ºÐ¿¡°Ô µð¹ö±ëÇÏ´Â ½Ã°£À» ÁÙÀÏ ¼ö ÀÖ´Â ´õ ³ªÀº ¾ÆÀ̵ð¾î¿Í ÆÁµéÀ» Á¦°øÇÒ °ÍÀÌ´Ù. 1.1. ÇöÀç C++ ÄÄÆÄÀÏ·¯µéÀÌ Á÷¸éÇÑ ¹®Á¦µé C++ Àº CÀÇ super-set ÀÎ °ü°è·Î "C" ¾ð¾îÀÇ ¸ðµç ¾ÈÁÁÀº Á¡µéÀ» °®°í ÀÖ´Ù. ¿¹¸¦ µé¾î, "C" ÇÁ·Î±×·¡¹Ö¿¡¼­´Â ¸Þ¸ð¸® À¯Ãâ°ú ¸Þ¸ð¸® ¿À¹öÇ÷ο찡 ÈçÇÏ´Ù. ¿Ö³Ä¸é ´ÙÀ½°ú °°Àº ¿ë·Ê¶§¹®¿¡ ______________________________________________________________________ Datatype char * and char[] String functions like strcpy, strcat, strncpy, strncat, etc.. Memory functions like malloc, realloc, strdup, etc.. ______________________________________________________________________ char * ¿Í strcpyÀÇ »ç¿ëÀº "overflow" "fence past errors", ±×¸®°í "mem­ ory leaks" ·Î ÀÎÇÑ Áöµ¶ÇÑ ¸Þ¸ð¸® ¹®Á¦µéÀ» ¾ß±â½ÃŲ´Ù. ¸Þ¸ð¸® ¹®Á¦µéÀº µð¹ö±×ÇÏ±â ¸Å¿ì ¾î·Æ°í, °íÄ¡°í trouble-shootÇϴµ¥ ¸¹Àº ½Ã°£À» ¼Ò¸ð½ÃŲ´Ù. ¸Þ¸ð¸® ¹®Á¦µéÀº ÇÁ·Î±×·¡¸ÓµéÀÇ »ý»ê¼ºÀ» °¨¼Ò½ÃŲ´Ù. ÀÌ ¹®¼­´Â "C++"ÀÇ ¸Þ¸ð¸® ¹®Á¦¸¦ ÇؼÒÇÒ ¼ö ÀÖ´Â ¿©·¯°¡Áö ¾ð±ÞµÈ ¹æ¹ýµéÀ» ÅëÇØ ÇÁ·Î±×·¡¸ÓµéÀÇ »ý»ê¼ºÀ» Áõ ½ÃÅ°´Â°ÍÀ» µ½´Â´Ù. ¸Þ¸ð¸®¿Í °ü·ÃµÈ ¹ö±×µéÀº Å©·¢ÇÏ±â ¸Å¿ì ¾î·Æ°í ½ÉÁö¾î ¼÷·ÃµÈ ÇÁ·Î±×·¡¸Óµéµµ ¸Þ¸ð¸®¿Í °ü·ÃµÈ ¹®Á¦Á¡µéÀ» µð¹ö±×Çϴµ¥ ¸îÀÏ, ¸îÁÖ È¤Àº ¸î´Þ±îÁö °É¸®±âµµ ÇÑ´Ù. ¿©·¯°³ÀÇ ¸Þ¸ð¸® ¹ö±×µéÀº ¸î°³¿ùµ¿¾È ÄÚµå¾È¿¡ "¼û¾î"ÀÖÀ» °ÍÀÌ°í ±×°ÍµéÀº ±â´ëÄ¡ ¾Ê¾Ò´ø ÇÁ·Î±×·¥ Ãæµ¹À» ¾ß±â½Ãų ¼ö ÀÖ´Ù. char * ÀÇ »ç¿ëÀº ¹Ì±¹°ú ÀϺ»¿¡¼­ µð¹ö±ë ÇÏ´Â ½Ã°£°ú ÇÁ·Î±×·¥ÀÇ ½ÇÇàÁ¤Áö·Î ¸Å³â 20¾ïºÒÀÇ ¼ÕÇظ¦ ¾ß±â½ÃÅ°°í ÀÖ´Ù. ¿©·¯ºÐÀÌ C++ ¿¡¼­ char * ¸¦ »ç¿ëÇϸé, ƯÈ÷ ¿©·¯ºÐÀÇ ÇÁ·Î±×·¥ÀÌ ¹é¸¸ÁÙ ÀÌ»óÀÇ Äڵ尡 ÀÖ´Ù¸é ±×°ÍÀº Á¤¸»·Î ¼ÕÇغ¸´Â ÀÏÀÌ´Ù, ±×·¡¼­ ´ÙÀ½ÀÇ ±â¼úµéÀÌ "C" ¾ð¾îÀÇ ¾àÁ¡À» ±Øº¹Çϱâ À§ÇØ ´ÙÀ½ÀÇ ±â¼úµéÀ» Á¦¾ÈÇÏ´Â °ÍÀÌ´Ù. C++ ÄÄÆÄÀÏ·¯µéÀº ÇÁ·Î±×·¡¸ÓµéÀÌ "char *" , "char[]" µ¥ÀÌÅÍ Å¸ÀÔ°ú strcpy, strcat, strncpy, strncat°ú °°Àº ÇÔ¼öµéÀ» »ç¿ëÇÏ´Â °ÍÀ» ¸·¾Æ¾ßÇÑ´Ù°í Á¦¾ÈÇÑ´Ù. char *, char[] ¿Í °°Àº µ¥ÀÌÅÍŸÀÔµé°ú strcpy, strcat °°Àº ÇÔ¼öµéÀº C++ÀÇ »ç¿ë¿¡ À־ ¹Ýµå½Ã ¿ÏÀüÈ÷ ±ÝÁöµÇ¾î¾ß¸¸ ÇÏ´Â ÇØ·Î¿î °ÍµéÀÌ´Ù!! ¸ðµç C++ ÇÁ·Î±×·¡¸ÓµéÀº char * and char[] ¸¦ »ç¿ëÇÏ´Â ´ë½Å¿¡ ÀÌ ¹®¼­¿¡ ³ª¿À´Â 'mychar class'¿Í STDLIB¿¡ Æ÷ÇÔµÈ 'string class' ¸¦ ¹Ýµå½Ã »ç¿ëÇØ¾ß ÇÑ´Ù. 'mychar class' ´Â »ý¼ºÀÚ¿Í ¼Ò¸êÀÚ¸¦ ÀÌ¿ëÇؼ­ ¸Þ¸ð¸® °ü¸®¸¦ ÀÚµ¿È­ÇÏ°í ltrim, substringµîµîÀÇ ¿©·¯ ÇÔ¼öµéÀ» Á¦°øÇÑ´Ù. C++ ÄÄÆÄÀÏ·¯¿¡ ÀÖ´Â 'string class' µµ ¶ÇÇÑ º¸ÀÚ. string class ´Â standard GNU C++ library ÀÇ ÀϺκÐÀÌ°í ¸¹Àº stringÁ¶ÀÛÇÔ¼ö Á¦°øÇÑ´Ù. string class' ¿Í 'mychar class' ¸¦ ¾²¸é char * datatypeÀ» ¾µ ÇÊ¿ä°¡ ¾ø¾îÁø´Ù. ¶ÇÇÑ, C++ ÇÁ·Î±×·¡¸ÓµéÀº 'malloc' À̳ª 'free'¸¦ ¾²´Â ´ë½Å 'new'¿Í class' ´Â ¿Ïº®ÇÏ°Ô char datatypeÀ» ´ë½ÅÇØ ¾²ÀÏ ¼ö ÀÖ´Ù. ´õ±¸³ª ÇÁ·Î±×·¡¸ÓµéÀº ¸Þ¸ð¸® ¹®Á¦¿Í ¸Þ¸ð¸® ¾ó·ÎÄÉÀ̼ǿ¡ ´ëÇؼ­ ÀüÇô °ÆÁ¤ÇÒ ÇÊ¿ä°¡ ¾øÀ¸´Ï ¾ó¸¶³ª ÀÌ·Î¿î °ÍÀΰ¡. GNU C++ ÄÄÆÄÀÏ·¯´Â char *, char[] datatypes ÀÇ Áö¿øÀ» ¹Ýµå½Ã ÁßÁöÇؾßÇϸç, char datatypeÀ» ÀÌ¿ëÇÑ ±¸ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇϱâ Çؼ­ ÄÄÆÄÀÏ·¯´Â "-fchar-datatype" ¶ó ºÒ¸®´Â ¿É¼ÇÀ» g++ ¸í·É¾î¿¡ ´õ Ãß°¡·Î Á¦°øÇØÁà¾ß ÇÑ´Ù. ¾ÕÀ¸·Î 2³â¾È¿¡ ¸ðµç C++ ÇÁ·Î±×·¥µéÀº 'mychar class' and 'string class' ¸¦ ¾²°Ô µÉ°ÍÀÌ°í char * and char[] ´Â »ç¶óÁö°Ô µÉ °ÍÀÌ´Ù. ÄÄÆÄÀÏ·¯´Â ¾ÈÁÁÀº ÇÁ·Î±×·¡ ½À°üÀ» ¹æÁöÇϵµ·Ï ³ë·ÂÇؾßÇÑ´Ù. 1.2. "C" ¸¦ ¾µ°ÍÀΰ¡ "C++" À» ¾µ°ÍÀΰ¡ ¾Æ´Ï¸é ÀÚ¹Ù¸¦ ¾µ°ÍÀΰ¡? ¸ðµç ÀÀ¿ëÇÁ·Î±×·¥À̳ª ÀÏ¹Ý ¸ñÀûÀÇ ÇÁ·Î±×·¡¹ÖÀ» À§Çؼ­´Â °´Ã¼ÁöÇâÀûÀÎ ¾ð¾îÀÎ "C++"À» ÀÌ¿ëÇؼ­ ÇÁ·Î±×·¡¹ÖÀ» Çϴ°ÍÀÌ ÃßõµÈ´Ù. "C++"ÀÇ °´Ã¼ÁöÇâ ±â´ÉÀ» ÃæºÐÈ÷ À¯¿ëÇÒ ¼ö ÀÖ´Ù. ÇÏÁö¸¸ -0À̳ª -03°ú °°Àº ÄÄÆÄÀÏ·¯ optimizer¿É¼ÇµéÀº C++ÀÇ ¼Óµµ¸¦ Áõ°¡½Ãų ¼ö ÀÖ´Ù. ¿äÁò¿£ "C" ¾ð¾î°¡ ¿î¿µÃ¼Á¦, µð¹ÙÀ̽º µå¶óÀ̹öµîÀ» °³¹ßÇϱâÀ§ÇÑ "½Ã½ºÅÛ ÇÁ·Î±×·¡¹Ö"¿¡ ÁÖ·Î ¾²ÀδÙ. ÀÚ¹Ù´Â À¥ ºê¶ó¿ìÀú³»¿¡¼­ ½ÇÇàµÇ´Â GUIÀ» °³¹ßÇϴµ¥ ´õ¿í ÀûÇÕÇÑ Ç÷§Æû¿¡ µ¶¸³µÈ ¾ð¾îÀÌÁö¸¸ ¸Å¿ì ´À¸®°Ô ½ÇÇàµÈ´Ù. C++ and HTML, DHTML °ú ´õºÒ¾î Fast-CGI¸¦ »ç¿ëÇÏ´Â°Ô ´õ ³ªÀº ¼º´ÉÀ» ¹ßÈÖÇϱâÀ§Çؼ­´Â C++ and HTML, DHTML °ú ´õºÒ¾î Fast-CGI¸¦ »ç¿ëÇÏ´Â°Ô ¹Ù¶÷Á÷ÇÏ´Ù. 2. ´Ù¿î·Îµå mychar ¸ðµç ÇÁ·Î±×·¥µé°ú ¿¹Á¦µéÀº ÀÌ ¹®¼­ÀÇ Ã·ºÎ¿¡ ÀÖ´Ù. ¿©·¯ºÐÀº ÇÑ°³ÀÇ tar zipÈ­ÀÏ·Î ´Ù¿î·Îµå ¹ÞÀ» ¼ö ÀÖ´Ù. mychar class, libraries, ±×¸®°í ¿¹Á¦ ÇÁ·Î±×·¥µéÀº ´ÙÀ½¿¡¼­ ´Ù¿î¹ÞÀ» ¼ö ÀÖ´Ù. o ¿©±â" http://www.aldev.8m.com "°¡¼­ C++Programming howto.tar.gz file ¸¦ Ŭ¸¯ÇϽÿÀ. o Mirror site : 3. mychar classÀÇ »ç¿ë ÀÖ´Ù. ¿©·¯ºÐÀº 'libmychar.a' ¸¦ includeÇØ¾ß ÇÏ°í library ¸¦ "C++" libraryµéÀÌ À§Ä¡ÇÑ /usr/lib directory¿¡ Ä«ÇÇÇؾßÇÑ´Ù ('libmychar.a'´Â ``Appendix H''¿¡ ÀÖ´Â makefile¿¡¼­ ¸¸µé ¼ö ÀÖ´Ù ). 'libmychar.a'À» »ç¿ëÇϱâ â À§Çؼ­´Â ¿©·¯ºÐÀÇ ÇÁ·Î±×·¥À» ´ÙÀ½°ú °°ÀÌ ÄÄÆÄÀÏÇϽÿÀ. ______________________________________________________________________ g++ example.cpp -lmychar ______________________________________________________________________ ´ÙÀ½ »ùÇÃÄڵ带 º¸½Ã¿À. ______________________________________________________________________ mychar aa; aa = " Washington DC is the capital of USA "; // You can use aa.val like a 'char *' variable in programs !! for (unsigned long tmpii = 0; tmpii < aa.length(); tmpii++) { fprintf(stdout, "aa.val[%ld]=%c ", tmpii, aa.val[tmpii]); } // Using pointers on 'char *' val ... // Note: You must use a temporary local variable and assign the // pointer to aa.val. If you directly use aa.val and when // aa.val is incremented with aa.val++, then aa will go // call destructor and later when aa.val is accessed that // will cause core dump !! for (char *tmpcc = aa.val; *tmpcc != 0; tmpcc++) { // MUST use temporary variable tmpcc !! See note above. fprintf(stdout, "aa.val=%c ", *tmpcc); } ______________________________________________________________________ mychar class ¸¦ Á¤ÀÇÇÑ ¿ÏÀüÇÑ ¿¹Á¦ ÇÁ·Î±×·¥ "example_mychar.cpp" Àº ``Appendix A''¿¡ ÀÖ°í mychar class ´Â ``Appendix B''¿¡ ÀÖ´Ù. 3.1. ¿¬»êÀÚµé o Equal to == o Not equal to != o Assignment = o Add to itself and Assignment += o String concatenation or addition + ¿¬»êÀÚµéÀ» »ç¿ëÇÑ ¿¹Á¦ ___________________________________________________________________ mychar aa; mychar bb("Bill Clinton"); aa = "put some value string"; // assignment operator aa += "add some more"; // Add to itself and assign operator aa = "My name is" + " Alavoor Vasudevan "; // string cat operator if (bb == "Bill Clinton") // boolean equal to operator cout << "bb is eqaul to 'Bill Clinton' " << endl; if (bb != "Al Gore") // boolean 'not equal' to operator cout << "bb is not equal to 'Al Gore'" << endl; ___________________________________________________________________ 3.2. ÇÔ¼öµé o ÇöÀç ¹®ÀÚ¿­ ±æÀÌ length() o ¹®ÀÚ¿­ ¿ÞÂÊ À߶󳻱â. óÀ½¿¡ ³ª¿À´Â °ø¹é-»õÁÙ, ÅÜ-Á¦°ÅÇϱâ ltrim() o ¹®ÀÚ¿­ ¿À¸¥ÂÊ À߶󳻱â. µû¶ó³ª¿À´Â °ø¹é-»õÁÙ, ÅÜ- Á¦°ÅÇϱâ rtrim() o óÀ½°ú ³ªÁß¿¡ ³ª¿À´Â °ø¹é Á¦°ÅÇϱâ trim() o µû¶ó³ª¿À´Â »õÁÙ Á¦°ÅÇϱâ chop() o ¹®ÀÚ¿­À» ´ë¹®ÀÚ·Î ¹Ù²Ù±â to_upper() o ¹®ÀÚ¿­À» ¼Ò¹®ÀÚ·Î ¹Ù²Ù±â to_lower() o ½Ç¼ö°ªµéÀ» ¹Ý¿Ã¸²Çϰųª ³»¸²Çϱâ roundf(float input_val, short precision) o double°ªµéÀ» ¹Ý¿Ã¸²Çϰųª ³»¸²Çϱâ roundd(double input_val, short precision) o startÀ§Ä¡¿¡¼­ºÎÅÍ ¹®ÀÚ¿­ substr°ú ÀÏÄ¡ÇÏ´Â À§Ä¡ ã¾ÆÁÖ±â pos(char *substr, unsigned long start) o Explodes the string and returns the list in the list-head pointer explodeH explode(char *seperator) o Implodes the strings in the list-head pointer explodeH and returns the mychar variable implode(char *glue) o ¸®½ºÆ® Çìµå Æ÷ÀÎÅÍ explodeHÀÇ ¹®ÀÚ¿­À» ºÙÀÌ°í mychar º¯¼ö¹Ýȯ join(char *glue) o ÀÔ·Â ¹®ÀÚ¿­À» n¹ø ¹Ýº¹ repeat(char *input, unsigned int multiplier) o ¹®ÀÚ¿­ÀÇ ±ÛÀÚ¸¦ ¿ª¼øÀ¸·Îreverse() o ¹®ÀÚ¿­ ¡®needle¡¯À» °ÇÃÊ´õ¹Ì ¡®val¡¯¿¡¼­ ã¾Æ ¡®str¡¯·Î ¹Ù²Ù±â replace(char *needle, char *str) o Char¸¦ ¹ø¿ª str_tr(char *from, char *to) o ÅؽºÆ® ¹®ÀÚ¿­À» Áß¾Ó¿¡ center(int length, char padchar = o ¿ø·¡ ¹®ÀÚ¿­ÀÇ °ø¹é¹®ÀÚ¸¦ ¡®number¡¯°³ÀÇ ¡®padchar¡¯·Î ¹Ù²Ù¾î ÁØ´Ù. ¸Ç ¾Õ°ú µÚÀÇ °ø¹éÀº Ç×»ó Á¦°ÅµÈ´Ù. ¸¸¾à ¡®number¡¯°¡ ¾ø°Å³ª 0À̸é, ¹®ÀÚ¿­ ¾ÈÀÇ ¸ðµç °ø¹éÀÌ Á¦°ÅµÈ´Ù.¡®number¡¯ÀÇ ±âº»°ªÀº 0ÀÌ°í ¡®padchar¡¯ÀÇ ±âº»°ªÀº ¡®¡¯. space(int number = 0, char padchar = ' o ¡®start¡¯¿Í ¡¯end¡¯¸¦ Æ÷ÇÔÇÑ ¸ðµç ¹®ÀÚµé·Î ÀÌ·ç¾îÁø ¹®ÀÚ¿­ ¹Ýȯ xrange(char start, char end) o ¡®list¡¯¿¡ µé¾î ÀÖ´Â ¸ðµç ¹®ÀÚ Á¦°Å. ¡®list¡¯ÀÇ ±âº»¹®ÀÚ´Â °ø¹é¹®ÀÚ ¡® ¡¯ compress(char *list) o ¡®start¡¯ À§Ä¡¿¡¼­ºÎÅÍ ¡®length¡¯°³ ¹®ÀÚ¸¦ ¹®ÀÚ¿­¿¡¼­ Á¦°Å. ¸¸¾à ¡®statr¡¯°¡ ¹®ÀÚ¿­ ±æÀ̺¸´Ù ´õ ±æ¸é ¹®ÀÚ¿­Àº º¯ÇÏÁö ¾Ê´Â´Ù. delstr(int start, int length) o ¡®start¡¯¿¡¼­ ºÎÅÍ ¡®newstr¡¯¸¦ val¿¡ »ðÀÔÇÑ´Ù. ¡®newstr¡¯Àº ¡®length¡¯°³ ¹®ÀÚ·Î ¸ÂÃçÁø´Ù. ±âº» ¡®length¡¯´Â newstrÀÇ ¹®ÀÚ¿­ ±æÀÌ insert(char *newstr, int start = 0, int length = 0, char padchar = ') o Val¾ÈÀÇ °¡Àå ¿ÞÂÊ¿¡ ÀÖ´Â ¡®length¡¯°³ÀÇ ¹®ÀÚ¿­À» ¹Ýȯ. ¹®ÀÚ¿­ ¿ÞÂÊ ÁÙ¸ÂÃ߱⿡ ºü¸¥ ¹æ¹ý left(int length = 0, char padchar = ' ') o Val¾ÈÀÇ °¡Àå ¿À¸¥ÂÊ¿¡ ÀÖ´Â ¡®length¡¯°³ÀÇ ¹®ÀÚ¿­À» ¹Ýȯ. ¹®ÀÚ¿­ ¿À¸¥ÂÊ ÁÙ¸ÂÃ߱⿡ ºü¸¥ ¹æ¹ý right(int length = 0, char padchar = ' o ¡®newstr¡¯°¡ val¾È¿¡ ¡®start¡¯¿¡¼­ ºÎÅÍ µ¤¾î ¾º¿©Áø´Ù. ¡®newstr¡¯Àº ¡®length¡¯°³ÀÇ ¹®ÀÚ·Î ¸ÂÃçÁø´Ù. ±âº» ¡®length¡¯Àº newstrÀÇ ±æÀÌ overlay(char *newstr, int start = 0, int length = 0, char padchar = ' ') o ¹®ÀÚ¿­Áß ºÎºÐÀÇ »©³½´Ù. substr(int start, int length = 0) o regx¶û óÀ½ ÀÏÄ¡ÇÏ´Â °÷À» ã´Â´Ù. at(char *regx) o Regx¾ÕÀÇ ¹®ÀÚ¿­À» ¹Ýȯ before(char *regx) o RegxeµÚÀÇ ¹®ÀÚ¿­À» ¹Ýȯ after(char *regx) o ¹®ÀÚ¿­ÀÌ NULLÀ̸é Âü°ª ¹Ýȯ isnull() o ¹®ÀÚ¿­À» NULL·Î clear() 3.3. ±âŸ ÇÔ¼öµé ±âŸ mychar ÇÔ¼öµéÀ» ¿©±â¿¡ ¸ð¾ÆµÎ¾ú´Ù. ÇÏÁö¸¸ À̰͵éÀ» »ç¿ëÇÏÁö´Â ¸¶¶ó. ´ë½Å '+', '+=', '==' µî°ú °°Àº ¿¬»êÀÚµéÀ» »ç¿ëÇ϶ó. À̰͵éÀº 'mychar' class 'private'¸â¹öµéÀÌ´Ù. o Copy string str_cpy(char *bb) o Long integer converted to string str_cpy(unsigned long bb) o Integer converted to string str_cpy(int bb) o Float converted to string str_cpy(float bb) o String concatenate a char * str_cat(char *bb) o String concatenate a int str_cat(int bb) o String concatenate a int str_cat(unsigned long bb) o String concatenate a float str_cat(float bb) o Is equal to mychar ? bool equalto(const mychar & rhs, bool type = false) o Is equal to char* ? bool equalto(const char *rhs, bool type = false) ¿¹¸¦ µé¾î Á¤¼ö¸¦ ¹®ÀÚ¿­·Î ¹Ù²Ù±â À§Çؼ­´Â ´ÙÀ½°ú °°ÀÌ Ç϶ó. ___________________________________________________________________ mychar aa; aa = 34; //¿¬»êÀÚ ¡®=¡¯ ´Â int À» string ·Î ¹Ù²Û´Ù. cout << "The value of aa is : " << aa.val << endl; aa = 234.878; // ¿¬»êÀÚ '=' ´Â float À» string·Î ¹Ù²Û´Ù. cout << "The value of aa is : " << aa.val << endl; aa = 34 + 234.878; cout << "The value of aa is : " << aa.val << endl; // aa ´Â '268.878' ·Î µÈ´Ù. // mychar¸¦ cast ÇØ¾ß ÇÑ´Ù. aa = (mychar) 34 + " Honourable President Ronald Reagan " + 234.878; cout << "The value of aa is : " << aa.val << endl; // '34 Honourable President Ronald Reagan 234.878' ·Î Ãâ·ÂµÈ´Ù. ___________________________________________________________________ 4. C++ Zap (Delete) ¸í·É¾î C++ ÀÇ delete °ú new ¸í·É¾î´Â "C"ÀÇ malloc °ú free ÇÔ¼öº¸´Ù ÈξÀ ³´´Ù. malloc °ú free ´ë½Å¿¡ new ¿Í zap (delete) ¸í·É¾î¸¦ °¡´ÉÇÑ ¸¹ÀÌ ¾²µµ·Ï ÇÏÀÚ. delete¸í·É¾î¸¦ ´õ È®½ÇÈ÷ »ç¿ëÇϱâ À§Çؼ­ Zap() ¸í·É¾î¸¦ ¸¸µéÀÚ. zap() ¸í·É¾î´Â ´ÙÀ½°ú °°ÀÌ Á¤ÀÇµÉ ¼ö ÀÖ´Ù. ______________________________________________________________________ /* **¿Ïº®ÇÏ°í Æ°Æ°ÇÑ ¸ÅÅ©·Î¸¦ ¸¸µé±â À§ÇØ do while À» »ç¿ëÇÑ´Ù. **¿¹¸¦ µé¾î, ¸¸¾à "do-while"À» ¾²Áö ¾ÊÀ¸¸é, ´ÙÀ½°ú °°ÀÌ µÉ **°ÍÀÌ´Ù ** if (bbint == 4) ** aa = 0 ** else ** zap(aptr); //¹®Á¦¹ß»ý! aptrÀÌ Ç×»ó NULL·Î µÉ °ÍÀÌ´Ù */ #define zap(x) do { delete(x); x = NULL; } while (0) ______________________________________________________________________ ÀÚ ÀÌÁ¦ ¸ðµç Æ÷ÀÎÅ͵éÀÌ ³Î Æ÷ÀÎÅÍ·Î »ý¼ºµÈ´Ù°í °¡Á¤À» ÇÑ´Ù¸é ÀÏ·ÃÀÇ zap() ¸í·É¾î·Î ´ÙÀ½°ú °°ÀÌ new·Î »ý±ä°ÍµéÀ» ¾ÈÀüÇÏ°Ô »èÁ¦ ÇÒ ¼ö ÀÖ°í ¾ÆÁ÷ new·Î »ý±âÁö ¾ÊÀº °ÍµéÀ» Áö¿ìÁö ¾ÊÀ» ¼ö ÀÖ´Ù. ¿¹¸¦ µé¾î, ______________________________________________________________________ zap(pFirstname); zap(pFirstname); // no core dumps !! Because pFirstname is NULL now zap(pFirstname); // no core dumps !! Because pFirstname is NULL now zap(pLastname); zap(pJobDescription); ______________________________________________________________________ ÀÌ°ÍÀº ÀüÇô ½Å±âÇÑ °ÍÀÌ ¾Æ´Ï´Ù. ÀÌ°ÍÀº ´ÜÁö ¹Ýº¹µÇ´Â Äڵ带 ¼¼À̺êÇÏ°í ´õ Àбâ ÁÁ°Ô ¸¸µå´Â °ÍÀÌ´Ù. zap() ¸í·É¾î¿¡¼­ typecast¿¡ ÁýÂøÇÏÁö ¸¶¶ó - ¸¸¾à zap() ¸í·É¾î À§¿¡¼­ ¹º°¡ ¿¡·¯°¡ »ý±â¸é ±×°Ç ¾îµò°¡¿¡¼­ ´Ù¸¥ ¿¡·¯°¡ ÀÖÀ» °¡´É¼ºÀÌ Å©±â ¶§¹®ÀÌ´Ù. ¶ÇÇÑ ``my_malloc()'' , my_real­ loc() ±×¸®°í my_free()´Â ´õ ±ú²ýÇÏ°í additional checksÀÌ Àֱ⶧¹®¿¡ malloc(), realloc() and free(), ´ë½Å¿¡ »ç¿ëµÇ¾î¾ß ÇÑ´Ù. ¿¹¸¦ µé¾î ``my_malloc()'' °ú my_free() ÇÔ¼ö¸¦ »ç¿ëÇÑ mychar.h" º¸¶ó. ÁÖÀÇ: 'new' ·Î ÀâÇôÁø ¸Þ¸ð¸®À» free()·Î Ç®°Å³ª ¶Ç´« mallocÀ¸·Î ÀâÇôÁø ¸Þ¸ð¸®¸¦ 'delete' Ç®Áö¸¶¶ó. ÀÌ·Ä °æ¿ì °á°ú¸¦ ¿¹ÃøÇÒ ¼ö ¾ø´Ù. 5. my_malloc °ú my_freeÀÇ »ç¿ë malloc °ú reallocÀ» ÇÇÇÏ°í °¡´ÉÇÑ ÇÑ new and zap(delete)À» ¸¹ÀÌ ¾²µµ·Ï ÇÏÀÚ. ÇÏÁö¸¸ °¡²ûÀº "C++"¿¡¼­ "C" ½ºÅ¸ÀÏÀÇ ¸Þ¸ð¸® ¾ó·ÎÄÉÀ̼ÇÀ» ½á¾ßÇÒ ÇÊ¿ä°¡ ÀÖÀ» ¼öµµ ÀÖ´Ù. ÇÔ¼ö my_malloc() , my_realloc() and my_free()¸¦ ½á¶ó. ÀÌ ÇÔ¼öµéÀº allocations °ú initialisationsÀ» ÀûÀýÈ÷ ÇÏ°í ¸Þ¸ð¸® ¹®Á¦µéÀ» ¹æÁöÇÑ´Ù. ¶ÇÇÑ ÀÌ ÇÔ¼öµéÀº (DEBUG ¸ðµå¿¡¼­) ¾ó·ÎÄÉÀÌÆ®µÈ ¸Þ¸ð¸®¸¦ ÃßÀûÇÏ°í ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ±â Àü°ú ÈÄÀÇÃÑ ¸Þ¸ð¸® »ç¿ëÀ» ÇÁ¸°Æ®ÇÑ´Ù. ÀÌ°ÍÀº ¿©·¯ºÐ¿¡°Ô ¸Þ¸ð¸® À¯ÃâÀÌ ÀÖ´ÂÁöÀÇ ¿©ºÎ¸¦ ¾Ë·ÁÁØ´Ù. my_malloc °ú my_realloc Àº ¾Æ·¡¿Í °°ÀÌ Á¤ÀǵȴÙ. ÀÌ°ÍÀº Á¶±Ý ´õ ¸¹Àº ¸Þ¸ð¸®(SAFE_MEM = 5) ¸¦ ÇÒ´çÇÏ°í °ø°£À» ÃʱâÈ­ÇÑ´Ù. ±×¸®°í ¸¸¾à¿¡ ÇÁ·Î±×·¥¾È¿¡ ÀÌ¹Ì ÇÒ´çÀÌ µÇ¾î ÀÖÀ¸¸é ÇÒ´çÀÌ µÇÁö ¾Ê´Â´Ù. 'call_check(), remove_ptr()' ÇÔ¼ö´Â ¿ÀÁ÷ DEBUG°¡ makefile¿¡¼­ Á¤ÀÇ µÇ¾úÀ»¶§¿¡¸¸ ÀÛµ¿ÀÌ µÇ°í ÀÌ ÇÔ¼öµéÀº ((void)0) ( Áï NULL for non- debug production release.) ¿¡ assigned µÈ´Ù. ±×µéÀº »ç¿ëµÈ ÃÑ ¸Þ¸ð¸®¸¦ ÃßÀûÇÏ´Â °ÍÀ» °¡´ÉÄÉ ÇÑ´Ù. ______________________________________________________________________ void *local_my_malloc(size_t size, char fname[], int lineno) { size_t tmpii = size + SAFE_MEM; void *aa = NULL; aa = (void *) malloc(tmpii); if (aa == NULL) raise_error_exit(MALLOC, VOID_TYPE, fname, lineno); memset(aa, 0, tmpii); call_check(aa, tmpii, fname, lineno); return aa; } char *local_my_realloc(char *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpjj = 0; if (aa) // aa != NULL tmpjj = strlen(aa); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (char) * (tmpqq); aa = (char *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); aa[tmpqq-1] = 0; unsigned long kk = tmpjj; if (tmpjj > tmpqq) kk = tmpqq; for ( ; kk < tmpqq; kk++) aa[kk] = 0; call_check(aa, tmpii, fname, lineno); return aa; } ______________________________________________________________________ my_malloc ÇÁ·Î±×·¥ÀÇ full implementation À» À§Çؼ­ my_malloc.cpp. ¿Í Çì´õ È­ÀÏ my_malloc.h. À» º¸¶ó. my_malloc °ú my_free »ç¿ë¿¹´Â ´ÙÀ½°ú °°´Ù. ______________________________________________________________________ char *aa; int *bb; float *cc; aa = (char *) my_malloc(sizeof(char)* 214); bb = (int *) my_malloc(sizeof(int) * 10); cc = (float *) my_malloc(sizeof(int) * 20); aa = my_realloc(aa, sizeof(char) * 34); bb = my_realloc(bb, sizeof(int) * 14); cc = my_realloc(cc, sizeof(float) * 10); ______________________________________________________________________ my_realloc ¿¡¼­´Â º¯¼ö ÀÚü°¡ Àü´ÞµÇ°í, Á¤È®ÇÑ my_realloc ÀÌ ºÒ·ÁÁö±â¶§¹®¿¡ (Áï ÀûÀýÇÑ µ¥ÀÌŸ ŸÀÔ Æ÷ÀÎÅÍ°¡ ¹ÝȯµÇ±â¶§¹®¿¡) µ¥ÀÌŸŸÀÔÀ» º¯È¯ÇÒ ÇÊ¿ä°¡ ¾ø´Ù´Â °ÍÀ» ÁÖÁöÇ϶ó. my_reallocÀº char*, int* ±×¸®°í float*¸¦ À§ÇÑ Áߺ¹µÈ(overloaded) ÇÔ¼öµéÀ» °®°í ÀÖ´Ù. 6. Debug È­Àϵé C++ À̳ª C ÇÁ·Î±×·¥À» µð¹ö±×ÇÏ·Á¸é debug.h È­ÀÏÀ» include½ÃÅ°°í debug.h ÇÔ¼ö¸¦ ¿¬°á½ÃÅ°µµ·Ï 'Makefile' ¾È¿¡¼­ DEBUG¸¦ Á¤ÀÇÇضó. '-DDEBUG' ¸¦ »èÁ¦Çϸé debug ÇÔ¼ö calls´Â ((void)0) i.e. NULL·Î µÈ´Ù. ±×·¯¹Ç·Î ÇÁ·ÎÁ§Æ®ÀÇ ÃÖÁ¾ production release ¹öÀü¿¡ ¾Æ¹«·± ¿µÇâÀ» ³¢Ä¡Áö ¾Ê´Â´Ù. ¿©·¯ºÐÀº ÇÁ·Î±×·¥¿¡¼­ debug ÇÔ¼öµéÀ» ¸¶À½´ë·Î »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç production ½ÇÇàÈ­ÀÏÀÇ Å©±â¸¦ Áõ°¡½ÃÅ°Áö ¾Ê´Â´Ù. debug ·çƾÀÇ ±¸ÇöÀ» º¸·Á¸é``debug.cpp'' ±×¸®°í debug.h ¿Í debug ÇÔ¼ö¸¦ »ç¿ëÇÑ »ùÇÃÀ» º¸±âÀ§Çؼ­´Â ``my_malloc.cpp'' È­ÀÏÀ» º¸¶ó. »ùÇà ``Makefile'' À» º¸¶ó. 7. C++ Online ¹®¼­µé ´ÙÀ½ÀÇ C++ »çÀÌÆ®µéÀ» ¹æ¹®ÇØ º¸¶ó. :- o C++ Crash-proof site o C++ Memory site ÀÎÅͳݿ¡´Â ¼ö¸¹Àº C++ °ü·Ã ¹®¼­µéÀÌ ÀÖ´Ù. Yahoo, Lycos, Infoseek, ±×¸®°í Excite ¿Í °°ÀÎ ¼­Ä¡¿£Áø¿¡ °¡¼­ 'C++ tutorials' 'C++ references' 'C++ books' À» Å°¿öµå·Î ŸÀÔÀ» Çϸé ãÀ» ¼ö ÀÖ´Ù. Advanced search ¸¦ Ŭ¸¯Çؼ­ ¼­Ä¡ °á°úÀÇ ºÐ·ù¸¦ Á¼Èú ¼öµµ ÀÖ°í ¾îÈÖ³ª ±¸ÀýÀ» Á¤È®È÷ ½á¼­ ¼­Ä¡ÇÒ ¼öµµ ÀÖ´Ù. o o o o o 7.1. C++ Æ©Å͸®¾óµé ÀÎÅͳݿ¡ »ç¿ë°¡´ÉÇÑ ¸¹Àº ¿Â¶óÀÎ Æ©Å͸®¾óµéÀÌ ÀÖ´Ù. ¼­Ä¡ ¿£Áø¿¡¼­ 'C++ tutorials' ¸¦ ŸÀÔÇؼ­ ãÀ» ¼ö ÀÖ´Ù. 7.2. C++ ÄÚµù Ç¥ÁØ ´ÙÀ½°ú °°Àº C++ ÄÚµù URLµéÀ» °¡ º¸ÀÚ. o C++ coding standard o Coding standards from Possibility o Coding standards from Ambysoft o Rules and recommendations o Indent and annotate o Elemental rules o C++ style doc 7.3. C++ Äü ·¹ÆÛ·±½º ¼­Ä¡¿£Áø¿¡¼­ 'C++ Reference' ¸¦ ŸÀÔÇؼ­ ãÀ» ¼ö ÀÖ´Ù. 7.4. C++ À¯Áî³Ý ´º½º±×·ìµé o C++ newsgroups : o C++ newsgroups : 8. ¸Þ¸ð¸® µµ±¸µé ´ÙÀ½ÀÇ ¸Þ¸ð¸® µð¹ö±ë µµ±¸µéÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. o ¸®´ª½º contrib cdrom¿¡ ´ëÇؼ­´Â mem_test*.rpm ÆÑÅ°Áö¸¦ º¸¸é µÈ´Ù. o ¸®´ª½º ½Ãµð·Ò¿¡ ´ëÇؼ­´Â ElectricFence*.rpm ÆÑÅ°Áö¸¦ º¸¸é µÈ´Ù. o Purify Tool from Rational Software Corp o Insure++ Tool from Parasoft Corp o Linux Tools at o Yahoo, Lycos, Excite, ȤÀº Mamma.com °ú °°Àº ÀÎÅÍ³Ý ¼­Ä¡¿£Áø¿¡¼­ "Linux memory debugging tools"À» Å°¿öµå·Î ŸÀÔÀ» Çؼ­ ã¾Æº¸¸é µÈ´Ù 9. °ü·Ã URLµé C, C++ °ú °ü·ÃµÈ ´ÙÀ½ÀÇ ÀÎÅÍ³Ý »çÀÌÆ®¸¦ ¹æ¹®ÇØ º¸ÀÚ. o Vim color text editor for C++, C o C++ Beautifier HOWTO o CVS HOWTO for C++ programs o Linux goodies main site o Linux goodies mirror site 10. ÀÌ ¹®¼­ÀÇ ´Ù¸¥ Æ÷¸äµé ÀÌ ¹®¼­´Â 10¿©Á¾ÀÇ ´Ù¸¥ Æ÷¸ä -DVI, Æ÷½ºÆ®½ºÅ©¸³Æ®, ·¹ÀÌÅؽº, LyX, GNU- info, HTML, RTF(Rich Text Format), Plain-text, Unix man pages ±×¸®°í SGML - À¸·Î ³ª¿Ô´Ù. o ÀÌ HOWTO ¹®¼­´Â HTML, DVI, Postscript ȤÀº SGML Æ÷¸äÀ¸·Î µÈ ÇÑ°³ÀÇ tarÈ­ÀÏ·Î ´ÙÀ½¿¡¼­ º¼ ¼ö ÀÖ´Ù. or o Plain text Æ÷¸äÀº: or o ºÒ¾î³ª µ¶ÀϾî, ½ºÆäÀξî, Áß±¹¾î ÀϺ»¾î¿Í °°Àº ¿Ü±¹¾î·Î ¹ø¿ªµÈ °ÍÀº or ¿¡¼­ º¼ ¼ö ÀÖ´Ù. ¹ø¿ªÀ» µµ¿Í ÁÖ°íÀÚ ÇÏ´Â »ç¶÷Àº ´©±¸³ª ȯ¿µÇÑ´Ù. À̹®¼­´Â "SGML" ÅøÀ» ÀÌ¿ëÇؼ­ ¾²¿©Á³À¸¸ç, "SGML" ÅøÀº The document is written using a tool called "SGML tool" which can be got from - ¿¡¼­ ±¸ÇÒ ¼ö ÀÖ´Ù. ¼Ò½º¸¦ ÄÄÆÄÀÏ ÇÏ¸é ´ÙÀ½°ú °°Àº ¸í·É¾î¸¦ º¸°Ô µÉ °ÍÀÌ´Ù. o sgml2html C++Programming-HOWTO.sgml (to generate html file) o sgml2rtf C++Programming-HOWTO.sgml (to generate RTF file) o sgml2latex C++Programming-HOWTO.sgml (to generate latex file) ÀÌ ¹®¼­´Â ´ÙÀ½¿¡ ÀÖ´Ù. o ¶ÇÇÑ ´ÙÀ½ÀÇ ¹Ì·¯ »çÀÌÆ®¿¡¼­ ÀÌ ¹®¼­¸¦ ãÀ» ¼ö ÀÖ´Ù. o o o o o (³×Æ®¿öÅ© ÁּҸ鿡¼­) °¡±î¿î ´Ù¸¥ ¹Ì·¯ »çÀÌÆ®µéÀº ¿¡¼­ ãÀ» ¼ö ÀÖ´Ù. »çÀÌÆ®¸¦ ¼±ÅÃÇÏ°í /LDP/HOWTO/C++Programming-HOWTO.html µð·ºÅ丮·Î °¡¸é µÈ´Ù. ÀÌ ¹®¼­¸¦ dvi Æ÷¸äÀ¸·Î º¸±âÀ§Çؼ­´Â xdvi ÇÁ·Î±×·¥À» »ç¿ëÇÏ¸é µÈ´Ù. xdvi ÇÁ·Î±×·¥Àº ·¹µåÇò ¸®´ª½ºÀÇ tetex-xdvi*.rpm ÆÑÅ°Áö ¾È¿¡ ÀÖÀ¸¸ç Á¦¾îÆÇ|ÀÀ¿ëÇÁ·Î±×·¥(Applications) | Publishing | TeX ¸Þ´º¹öÆ°À» ÅëÇؼ­ ãÀ» ¼ö ÀÖ´Ù. dvi ¹®¼­¸¦ Àбâ À§Çؼ­´Â xdvi -geometry 80x90 howto.dvi ¶ó´Â ¸í·É¾î¸¦ ÁÖ¾î¾ß ÇÑ´Ù. ±×¸®°í ¸¶¿ì½º·Î À©µµ¿ìÀÇ Å©±â¸¦ Á¶ÀýÇÏ°í xdviÀÇ ¸ÞÀÎ ÆäÀÌÁö¸¦ º¸¸é µÈ´Ù. À§¾Æ·¡·Î ¿òÁ÷À̱â À§Çؼ­´Â È­»ìÇ¥ Å°³ª ÆäÀÌÁö ¾÷, ÆäÀÌÁö ´Ù¿îµîÀÇ Å°¸¦ »ç¿ëÇϰųª 'f', 'd', 'u', 'c', 'l', 'r', 'p', 'n' ÀÇ ±ÛÀÚÅ°¸¦ À§·Î ¿Ã¸®°Å³ª ¾Æ·¡·Î Áß¾ÓÀ¸·Î ȤÀº ´ÙÀ½ ÆäÀÌÁö³ª ÀÌ Àü ÆäÀÌÁö·Î À̵¿Çϱâ À§Çؼ­ »ç¿ëÇÒ ¼öµµ ÀÖ´Ù. expert ¸Þ´º¸¦ ¾ø¾Ö·Á¸é 'x' ¸¦ ´©¸£¸é µÈ´Ù. È­ÀÏÀ» ÀÐÀ» ¼ö ÀÖ´Ù. °í½ºÆ®½ºÅ©¸³Æ® ÇÁ·Î±×·¥°ú gv ÇÁ·Î±×·¥Àº °¢°¢ ·¹µåÇò ¸®´ª½ºÀÇ ghostscript*.rpm ÆÑÅ°Áö¿¡ ÀÖ°í gv ÇÁ·Î±×·¥Àº gv*.rpm ÆÑÅ°Áö¿¡ ÀÖ°í, ControlPanel | Applications | Graphics ¸Þ´º¹öÆ°À» ÅëÇؼ­ À§Ä¡¸¦ ã¾Æ³¾ ¼ö ÀÖ´Ù. gv ÇÁ·Î±×·¥Àº °í½ºÆ®½ºÅ©¸³Æ®º¸´Ù »ç¿ëÀÚ°¡ Æí¸®Çϵµ·Ï ¸¸µé¾îÁ® ÀÖ´Ù. °í½ºÆ®½ºÅ©¸³Æ®¿Í gv´Â OS/2³ª À©µµ¿ì 95 ±×¸®°í NT¿Í °°Àº ´Ù¸¥ Ç÷¿Æû¿¡¼­µµ »ç¿ë °¡´ÉÇÏ´Ù. o Get ghostscript for Windows 95, OS/2, and for all OSes from Æ÷½ºÆ®½ºÅ©¸³Æ® ¹®¼­¸¦ ÀбâÀ§Çؼ­´Â gv howto.ps ¶ó´Â ¸í·É¾î¸¦ ¾´´Ù. °í½ºÆ®½ºÅ©¸³Æ®¸¦ »ç¿ëÇϱâ À§Çؼ­´Â ghostscript howto.ps ¸¦ ¾´´Ù. HTML Æ÷¸äÀÇ ¹®¼­´Â ³Ý½ºÄÉÀÌÇÁ ³×ºñ°ÔÀÌÅͳª ¸¶ÀÌÅ©·Î¼ÒÇÁÆ® ÀÎÅÍ³Ý ÀͽºÇ÷ξî, ·¹µåÇò ¹Ù·Ð À¥ ºê¶ó¿ìÀú ȤÀº ´Ù¸¥ À¥ ºê¶ó¿ìÀú¸¦ ½á¼­ ÀÐÀ» ¼ö ÀÖ´Ù latex, LyX ¹®¼­´Â LyX a "X-Windows" front end to latex À» ÀÌ¿ëÇØ ÀÐÀ» ¼ö ÀÖ´Ù. 11. ÀúÀÛ±Ç ÀúÀÛ±Ç Á¶Ç×Àº LDP (¸®´ª½º ¹®¼­ ÇÁ·ÎÁ§Æ®) ·Î¼­ GNU/GPL ÀÌ´Ù. LDP ´Â ÇϳªÀÇ GNU/GPLÇÁ·ÎÁ§Æ®ÀÌ´Ù. Ãß°¡·Î ¿ä±¸µÇ´Â °Íµé·Î¼­ ÀúÀÚÀÇ À̸§, À̸ÞÀÏ ÁÖ¼Ò, ±×¸®°í ¸ðµç º¹»çº»µé¿¡ ÀÌ ÀúÀÛ±Ç Á¶Ç׿¡ ´ëÇÑ ºÎºÐÀ» ³Ö¾îÁÖ¾î¾ß ÇÑ´Ù. ÀÌ ¹®¼­¸¦ Á¶±ÝÀÌ¶óµµ ¹Ù²Ù°Å³ª ¹º Ãß°¡ÇÏ°Ô µÇ¸é ÀÌ ¹®¼­ÀÇ ¸ðµç ÀúÀڵ鿡°Ô ±×°ÍÀ» ¾Ë·ÁÁֱ⠹ٶõ´Ù. 12. ÷ºÎ A example_mychar.cpp ¸ðµç ÇÁ·Î±×·¥µéÀº Download mychar ·Î ºÎÅÍ ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå ¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¾òÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ 'Text' ŸÀÔÀ¸·Î ÀúÀåÀ» ÇÏ¸é µÈ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ÀÌÁö¸¸ Ãß°¡·Î ¸ðµç º¹Á¦º»¿¡ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀ» //Æ÷ÇÔ½ÃÄÑÁÖ¾î¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** // ÄÄÆÄÀÏ ÇÏ·Á¸é( libmychar.a°¡ ÇöÀç µð·ºÅ丮¿¡ ÀÖ´Ù°í // °¡Á¤ÇÏ°í ) // g++ example_mychar.cpp -L. -lmychar #include // for putenv #include "mychar.h" ///////////////////////////////////////////////// //mychar »ç¿ë ¿¹Á¦ ÇÁ·Î±×·¥ ///////////////////////////////////////////////// int main(int argc, char **argv) { char p_name[1024]; sprintf(p_name, "PROGRAM_NAME=%s", argv[0]); putenv(p_name); print_total_memsize(); // in the beginning mychar aa, bb; //bb.str_cpy(" bbSTRing "); bb = " bbSTRing "; //+ ¿¬»êÀÚ Å×½ºÆ®Çϱâ //aa + " rhs "; // ¿©±â¼­´Â ¾î¶² Ãâ·Âµµ °®Áö ¾Ê°Ô µÉ°ÍÀÌ´Ù !! //¹Ýµå½Ã ´ÙÀ½ÁÙ¿¡ ³ª¿À´Â °Í ó·³ Á÷Á¢ fprintf ¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. fprintf(stdout, "\n0) aa.val is :%sEOF\n", (aa + " my rhs " ).val); //=¿¬»êÀÚ Å×½ºÆ®Çϱâ aa = " lhs " ; fprintf(stdout, "0-1) With operator= aa.val is :%sEOF\n", aa.val); //+ ¿¬»êÀÚ Å×½ºÆ® Çϱâ //aa + " rhs "; // ¿©±â¼­´Â ¾î¶² Ãâ·Âµµ °®Áö ¾Ê°Ô µÉ°ÍÀÌ´Ù !! //¹Ýµå½Ã ´ÙÀ½ÁÙ¿¡ ³ª¿À´Â °Í ó·³ Á÷Á¢ fprintf ¸¦ »ç¿ëÇØ¾ß ÇÑ´Ù. fprintf(stdout, "\n0) With lsh operator+, aa.val is :%sEOF\n", (" my lhs " + aa ).val); //aa.str_cpy(bb.val); aa = bb; aa.to_upper(); fprintf(stdout, "1) aa.val is :%sEOF\n", aa.val); aa = bb; aa.to_lower(); fprintf(stdout, "2) aa.val is :%sEOF\n", aa.val); aa = bb; aa.ltrim(); fprintf(stdout, "3) aa.val is :%sEOF\n", aa.val); aa = bb; aa.rtrim(); fprintf(stdout, "4) aa.val is :%sEOF\n", aa.val); aa = bb; aa.trim(); fprintf(stdout, "5) aa.val is :%sEOF\n", aa.val); aa = bb; aa = aa + " testing newlines \n\n\n\n"; aa.chop(); fprintf(stdout, "5-1) aa.val is :%sEOF\n", aa.val); aa = bb; aa = aa + " rhs "; fprintf(stdout, "6) aa.val is :%sEOF\n", aa.val); aa = bb; aa = " lhs " + aa; fprintf(stdout, "7) aa.val is :%sEOF\n", aa.val); // ¼ýÀÚ ´õÇϱ⠿¹Á¦ //aa = (mychar) 9989 + "kkk" + 33 ; aa = 9999; fprintf(stdout, "7-1) aa.val is :%sEOF\n", aa.val); aa = bb; aa = " lhs " + aa + " rhs " + " 9989 " + " 33 "; fprintf(stdout, "8) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = bb + "alkja " + " 99djd " ; fprintf(stdout, "9) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = (mychar) "alkja " + " 99djd " ; fprintf(stdout, "10) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa += (mychar) " al dev test kkk... " + " al2 slkj" + " al3333 "; fprintf(stdout, "11) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = aa + " add aa " + aa + aa + aa + " 1111 " + " 2222 " + aa + aa + aa + " 3333 "; fprintf(stdout, "12) aa.val is :%sEOF\n", aa.val); aa = "12345678"; aa.reverse(); fprintf(stdout, "13) aa.val is :%sEOF\n", aa.val); aa = " AA value "; aa = aa + " add aa " + aa + 1111 +" "+ 2222 + " " + 3.344 + aa; fprintf(stdout, "14) aa.val is :%sEOF\n", aa.val); aa.roundd(123456.0123456789012345, 13); fprintf(stdout, "15) double aa.val is :%sEOF\n", aa.val); aa.roundf(123456.0123456789, 13); fprintf(stdout, "16) float aa.val is :%sEOF\n", aa.val); // Test equal to operators aa = " AA value "; mychar cc(" AA value "); if (aa == cc) fprintf(stdout, "\naa=%s and cc=%s are equal!!\n", aa.val, cc.val); else fprintf(stdout, "\naa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val); cc = "CC"; if (aa == cc) fprintf(stdout, "\naa=%s and cc=%s are equal!!\n", aa.val, cc.val); else fprintf(stdout, "\naa=%s and cc=%s are NOT equal!!\n", aa.val, cc.val); if (aa == " AA value ") fprintf(stdout, "\naa=%s and string are equal!!\n", aa.val); else fprintf(stdout, "\naa=%s and string are NOT equal!!\n", aa.val); if (aa == " AA valuexxx ") fprintf(stdout, "\naa=%s and string are equal!!\n", aa.val); else fprintf(stdout, "\naa=%s and string are NOT equal!!\n", aa.val); //aa.val ¸¦ 'char *' º¯¼öó·³ ÇÁ·Î±×·¥¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Ù!! fprintf(stdout, "\n "); for (unsigned long tmpii = 0; tmpii < aa.length(); tmpii++) { fprintf(stdout, "aa.val[%ld]=%c ", tmpii, aa.val[tmpii]); } fprintf(stdout, "\n"); //'char *' val ...¿¡ Æ÷ÀÎÅÍ »ç¿ëÇϱâ fprintf(stdout, "\n "); for (char *tmpcc = aa.val; *tmpcc != 0; tmpcc++) { // MUST use temporary var tmpcc !! See note above. fprintf(stdout, "aa.val=%c ", *tmpcc); } fprintf(stdout, "\n"); print_total_memsize(); // in the end exit(0); } ______________________________________________________________________ 13. ÷ºÎ B mychar.h Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ //Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** //¸Þ¸ð¸®À¯ÃâÀ» ¹æÁöÇϱâÀ§Çؼ­´Â - a char class to manage character //variables //char[] ȤÀº char *´ë½Å mychar ³ª string class ¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. #ifndef __MYCHAR_H_ #define __MYCHAR_H_ //#include // iostreamÀº ÇÁ·Î±×·¥ÀÌ Ä¿Áö´Ï±î »ç¿ëÇÏÁö ¾Ê´Â´Ù. //#include //free() ¿Ímalloc() ¸¦ ¾²±âÀ§ÇØ #include // for strcpy() #include // for isspace() #include // for sprintf() #include // for sprintf() #include // for modf(), rint() #include "my_malloc.h" #include "debug.h" // debug_(name, value) debug2_(name, value, LOG_YES) const short INITIAL_SIZE = 50; const short NUMBER_LENGTH = 70; // ÃÖ¼ÒÇÑÀÇ ÇÔ¼ö¿Í º¯¼ö¸¦ °¡Áø ÀÛÀº Ŭ·¡½º (class) // This class to be kept small... ÀÌ Å¬·¡½º´Â °è¼Ó ÀÛ°Ô À¯ÁöµÉ°ÍÀÌ´Ù. class mychar { public: mychar(); mychar(char bb[]); // needed by operator+ mychar(int bb); // needed by operator+ mychar(unsigned long bb); // needed by operator+ mychar(float bb); // needed by operator+ mychar(double bb); // needed by operator+ mychar(const mychar & rhs); // Copy Constructor needed by operator+ ~mychar(); char *val; unsigned long length() { return strlen(val); } void ltrim(); void rtrim(); void trim(); void chop(); void to_upper(); void to_lower(); void roundf(float input_val, short precision); void decompose_float(long *integral, long *fraction); void roundd(double input_val, short precision); void decompose_double(long *integral, long *fraction); long pos(char substr[], unsigned long start); void explode(char *seperator); void implode(char *glue); void join(char *glue); void repeat(char *input, unsigned int multiplier); void reverse(); void replace(char *needle, char *str); void str_tr(char *from, char *to); void center(int length, char padchar = ' '); void space(int number = 0, char padchar = ' '); void xrange(char start, char end); void compress(char *list); void delstr(int start, int length); void insert(char *newstr, int start = 0, int length = 0, char padchar = ' '); void left(int length = 0, char padchar = ' '); void right(int length = 0, char padchar = ' '); void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' '); mychar substr(int start, int length = 0); mychar at(char *regx); // matches first match of regx mychar before(char *regx); // returns string before regx mychar after(char *regx); // returns string after regx bool isnull(); void clear(); // All Operators ... mychar operator+ (const mychar & rhs); friend mychar operator+ (const mychar & lhs, const mychar & rhs); mychar& operator+= (const mychar & rhs); // using reference will be faster mychar& operator= (const mychar & rhs); // using reference will be faster bool operator== (const mychar & rhs); // using reference will be faster bool operator== (const char *rhs); bool operator!= (const mychar & rhs); bool operator!= (const char *rhs); static list explodeH; // list head private: //static mychar *global_mychar; // for use in add operator //inline void free_glob(mychar **aa); void str_cpy(char bb[]); void str_cpy(int bb); // itoa void str_cpy(unsigned long bb); void str_cpy(float bb); // itof void str_cat(char bb[]); void str_cat(int bb); void str_cat(unsigned long bb); void str_cat(float bb); bool equalto(const mychar & rhs, bool type = false); bool equalto(const char *rhs, bool type = false); }; // Global variables are defined in mychar.cpp #endif // __MYCHAR_H_ ______________________________________________________________________ 14. ÷ºÎ C mychar.cpp Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ //Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** //¹®ÀÚ¿­ Ŭ·¡½º³ª ÀÌ Å¬·¡½º¸¦ »ç¿ëÇÑ´Ù. // //¸Þ¸ð¸®À¯ÃâÀ» ¹æÁöÇϱâÀ§Çؼ­´Â - a char class to manage character //variables //char[] ȤÀº char *´ë½Å mychar ³ª string class ¸¦ »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù. // ´ÙÀ½°ú °°ÀÌ ÄÄÆÄÀÏ ÇÒ °Í // g++ mychar.cpp #include "mychar.h" // Global variables .... //mychar *mychar::global_mychar = NULL; // global var list mychar::explodeH; mychar::mychar() { debug_("In cstr()", "ok"); val = (char *) my_malloc(sizeof(char)* INITIAL_SIZE); } mychar::mychar(char *bb) { unsigned long tmpii = strlen(bb); val = (char *) my_malloc(sizeof(char)* tmpii); strncpy(val, bb, tmpii); val[tmpii] = '\0'; //debug_("In cstr(char *bb) bb", bb); //debug_("In cstr(char *bb) val", val); #ifdef DEBUG //fprintf(stderr, "\nAddress of val=%x\n", & val); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG } mychar::mychar(int bb) { val = (char *) my_malloc(NUMBER_LENGTH); // integers 70 digits max sprintf(val, "%d", bb); } mychar::mychar(unsigned long bb) { val = (char *) my_malloc(NUMBER_LENGTH); // long 70 digits max sprintf(val, "%lu", bb); } mychar::mychar(float bb) { val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max sprintf(val, "%f", bb); } mychar::mychar(double bb) { val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max sprintf(val, "%f", bb); } // Copy Constructor needed by operator + mychar::mychar(const mychar & rhs) { // Do a deep-copy instead of compiler's default shallow copy copy-cstr debug_("In copy-cstr()", "ok"); unsigned long tmpii = strlen(rhs.val); val = (char *) my_malloc(sizeof(char)* tmpii); strncpy(val, rhs.val, tmpii); val[tmpii] = '\0'; } mychar::~mychar() { //debug_("In dstr val", val); #ifdef DEBUG //fprintf(stderr, "\nAddress of val=%x\n", & val); //fprintf(stderr, "\nAddress of this-pointer=%x\n", this); #endif // DEBUG my_free(val); //delete [] val; val = NULL; } // MUST use pointer-to-pointer **aa, otherwise the argument // is NOT freed !! /* inline void mychar::free_glob(mychar **aa) { debug_("called free_glob()", "ok" ); if (*aa != NULL) // (*aa != NULL) { debug_("*aa is not null", "ok"); delete *aa; *aa = NULL; } //else debug_("*aa is null", "ok"); //if (*aa == NULL) debug_("*aa set to null", "ok"); } */ // Explodes the string and returns the list in // the list-head pointer explodeH void mychar::explode(char *seperator) { char *aa = NULL, *bb = NULL; aa = (char *) my_malloc(length()); for (bb = strtok(aa, seperator); bb != NULL; bb = strtok(NULL, seperator) ) { mychar *tmp = new mychar(bb); mychar::explodeH.insert(mychar::explodeH.end(), *tmp); } my_free(aa); list::iterator iter1; // see file include/g++/stl_list.h debug_("Before checking explode..", "ok"); if (mychar::explodeH.empty() == true ) { debug_("List is empty!!", "ok"); } for (iter1 = mychar::explodeH.begin(); iter1 != mychar::explodeH.end(); iter1++) { if (iter1 == NULL) { debug_("Iterator iter1 is NULL!!", "ok" ); break; } debug_("(*iter1).val", (*iter1).val); } } // Implodes the strings in the list-head // pointer explodeH and returns the mychar class void mychar::implode(char *glue) { } // Joins the strings in the list-head // pointer explodeH and returns the mychar class void mychar::join(char *glue) { implode(glue); } // Repeat the input string n times void mychar::repeat(char *input, unsigned int multiplier) { // For example - // repeat("1", 4) returns "1111" if (!input) // input == NULL { val[0] = 0; return; } val = (char *) my_malloc(strlen(input) * multiplier); for (unsigned int tmpii = 0; tmpii < multiplier; tmpii++) { strcat(val, input); } } // Reverse the string void mychar::reverse() { // For example - // reverse() on "12345" returns "54321" char aa; unsigned long tot_len = length(); unsigned long midpoint = tot_len / 2; for (unsigned long tmpjj = 0; tmpjj < midpoint; tmpjj++) { aa = val[tmpjj]; // temporary storage var val[tmpjj] = val[tot_len - tmpjj - 1]; // swap the values val[tot_len - tmpjj - 1] = aa; // swap the values } } // Replace all occurences of string 'needle' with 'str' in the haystack 'val' void mychar::replace(char *needle, char *str) { // For example - // replace("AAA", "BB") on val = "some AAA and AAACC" // reurns val = "some BB and BBCC" } // Translate certain chars void mychar::str_tr(char *from, char *to) { // For e.g ("abcd", "ABC") translates all occurences of each // character in 'from' to corresponding character in 'to' } // Center the text void center(int length, char padchar = ' ') { // For example - // center(10, '*') on val="aa" returns "****aa****" // center(10) on val="aa" returns " aa " // The result is a string of 'length' characters with val centered in it. } // Formats the original string by placing of characters // between each set of blank-delimited words. Leading and Trailing blanks // are always removed. If is omitted or is 0, then all spaces are // in the string are removed. The default number is 0 and // default padchar ' ' void space(int number, char padchar = ' ') { // For example - // space(3) on val = "I do not know" // will return "I do not know" // space(1, '_') on val = "A deep black space" // will return "A_deep_black_space" // space() on val = "I know this" // will return "Iknowthis" } // The result is string comprised of all characters between // and including and void xrange(char start, char end) { // For example - // xrange('a', 'j') returns val = "abcdefghij" // xrange(1, 8) returns val = "12345678" } // Removes any characters contained in . The default character // for is a blank ' ' void compress(char *list) { // For example - // compress("$,%") on val = "$1,934" returns "1934" // compress() on val = "call me alavoor vasudevan" returns "callmealavoorvasudevan" } // Deletes a portion of string of characters from position. // If start is greater than the string length then string is unchanged. void delstr(int start, int length) { // For example - // delstr(3,3) on val = 'pokemon' returns 'poon' } // The in inserted into val beginning at . The will // be padded or truncated to characters. The default is // string length of newstr void insert(char *newstr, int start = 0, int length = 0, char padchar = ' ') { // For example - // insert("something new", 4, 20, '*') on val = "old thing" // returns "old something new*******thing" } // The result is string of chars madeup of leftmost chars in val. // Quick way to left justify a string. void left(int length = 0, char padchar = ' ') { // For example - // left(10) on val = "Wig" returns "Wig " // left(4) on val = "Wighat" returns "Wigh" } // The result is string of chars madeup of rightmost chars in val. // Quick way to right justify a string. void right(int length = 0, char padchar = ' ') { // For example - // right(10) on val = "never stop to saying" returns " to saying" // right(4) on val = "Wighat" returns "ghat" // right(6) on val = "4.50" returns " 4.50" } // The in overlayed into val beginning at . The will // be padded or truncated to characters. The default is // string length of newstr void overlay(char *newstr, int start = 0, int length = 0, char padchar = ' ') { // For example - // overlay("12345678", 4, 10, '*') on val = "oldthing is very bad" // returns "old12345678**ery bad" } // sub string mychar mychar::substr(int start, int length = 0) { if (!length) // length == 0 return(mychar(& val[start-1]) ); else { mychar tmp = mychar(& val[start-1]); tmp.val[length-1] = 0; return(tmp); } } // If string is literrally equal to .. or not equal to // If type is false then it is == bool mychar::equalto(const mychar & rhs, bool type = false) { if (type == false) // test for == { if (strlen(rhs.val) == length()) { if (!strncmp(rhs.val, val, length())) // == 0 return true; else return false; } else return false; } else // test for != { if (strlen(rhs.val) != length()) { if (!strncmp(rhs.val, val, length())) // == 0 return true; else return false; } else return false; } } // If string is literrally equal to .. or not equal to // If type is false then it is == bool mychar::equalto(const char *rhs, bool type = false) { if (type == false) // test for == { if (strlen(rhs) == length()) { if (!strncmp(rhs, val, length())) // == 0 return true; else return false; } else return false; } else // test for != { if (strlen(rhs) != length()) { if (!strncmp(rhs, val, length())) // == 0 return true; else return false; } else return false; } } // find position, matching substr beginning from start.. long mychar::pos(char *substr, unsigned long start) { char * tok; long res = -1; if ( !isnull() && (start < strlen(val) ) ) { tok = strstr(val + start, substr); if (tok == NULL) res = -1; else res = (long) (tok - val); } return res; } bool mychar::isnull() { if (val[0] == '\0') return true; else { if (val == NULL) return true; else return false; } } void mychar::clear() { val = (char *) my_realloc(val, 10); val[0] = '\0'; } // Remove trailing new-lines void mychar::chop() { unsigned long tmpii = strlen(val) - 1 ; for (; tmpii >= 0; tmpii--) { if (val[tmpii] == '\n') val[tmpii] = 0; else break; } } void mychar::ltrim() { // May cause problems in my_realloc since // location of bb will be destroyed !! char *bb = val; if (bb == NULL) return; while (isspace(*bb)) bb++; debug_("bb", bb); if (bb != NULL && bb != val) { debug_("doing string copy", "done"); //str_cpy(bb); // causes problems in my_realloc and bb is getting destroyed!! strcpy(val, bb); // strcpy is ok since val space is > bb space } else debug_("Not doing string copy", "done"); } void mychar::rtrim() { for (long tmpii = strlen(val) - 1 ; tmpii >= 0; tmpii--) { if ( isspace(val[tmpii]) ) val[tmpii] = '\0'; else break; } } void mychar::trim() { rtrim(); ltrim(); } void mychar::to_lower() { for (long tmpii = strlen(val); tmpii >= 0; tmpii--) { val[tmpii] = tolower(val[tmpii]); } } // Use for rounding off fractions digits of floats // Rounds-off floats with given precision and then // stores the result into mychar's val field // Also returns the result as a char * void mychar::roundf(float input_val, short precision) { float integ_flt, deci_flt; const short MAX_PREC = 4; debug_("In roundf", "ok"); if (precision > MAX_PREC) // this is the max reliable precision precision = MAX_PREC; // get the integral and decimal parts of the float value.. deci_flt = modff(input_val, & integ_flt); for (int tmpzz = 0; tmpzz < precision; tmpzz++) { debug_("deci_flt", deci_flt); deci_flt *= 10; } debug_("deci_flt", deci_flt); unsigned long deci_int = (unsigned long) ( rint(deci_flt) ); val = (char *) my_malloc(NUMBER_LENGTH); // float 70 digits max if (deci_int > 999) // (MAX_PREC) digits sprintf(val, "%lu.%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 99) // (MAX_PREC - 1) digits sprintf(val, "%lu.0%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 9) // (MAX_PREC - 2) digits sprintf(val, "%lu.00%lu", (unsigned long) integ_flt, deci_int); else sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } void mychar::roundd(double input_val, short precision) { double integ_flt, deci_flt; const short MAX_PREC = 6; if (precision > MAX_PREC) // this is the max reliable precision precision = MAX_PREC; debug_("In roundd", "ok"); // get the integral and decimal parts of the double value.. deci_flt = modf(input_val, & integ_flt); for (int tmpzz = 0; tmpzz < precision; tmpzz++) { debug_("deci_flt", deci_flt); deci_flt *= 10; } debug_("deci_flt", deci_flt); val = (char *) my_malloc(NUMBER_LENGTH); // double 70 digits max unsigned long deci_int = (unsigned long) ( rint(deci_flt) ); if (deci_int > 99999) // (MAX_PREC) digits sprintf(val, "%lu.%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 9999) // (MAX_PREC - 1) digits sprintf(val, "%lu.0%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 999) // (MAX_PREC - 2) digits sprintf(val, "%lu.00%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 99) // (MAX_PREC - 3) digits sprintf(val, "%lu.000%lu", (unsigned long) integ_flt, deci_int); else if (deci_int > 9) // (MAX_PREC - 4) digits sprintf(val, "%lu.0000%lu", (unsigned long) integ_flt, deci_int); else // (MAX_PREC - 5) digits sprintf(val, "%lu.00000%lu", (unsigned long) integ_flt, deci_int); } void mychar::to_upper() { for (long tmpii = strlen(val); tmpii >= 0; tmpii--) { val[tmpii] = toupper(val[tmpii]); } } void mychar::str_cpy(char bb[]) { debug_("In str_cpy bb", bb); if (bb == NULL) { val[0] = '\0'; return; } unsigned long tmpii = strlen(bb); if (tmpii == 0) { val[0] = '\0'; return; } debug_("In str_cpy tmpii", tmpii); debug_("In str_cpy val", val); val = (char *) my_realloc(val, tmpii); //val = new char [tmpii + SAFE_MEM_2]; debug_("In str_cpy bb", bb); strncpy(val, bb, tmpii); debug_("In str_cpy val", val); val[tmpii] = '\0'; debug_("In str_cpy val", val); } void mychar::str_cpy(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); str_cpy(tmpaa); } void mychar::str_cpy(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); str_cpy(tmpaa); } void mychar::str_cpy(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); str_cpy(tmpaa); } void mychar::str_cat(char bb[]) { unsigned long tmpjj = strlen(bb), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); debug_("val in str_cat() ", val); strncat(val, bb, tmpjj); } void mychar::str_cat(int bb) { char tmpaa[100]; sprintf(tmpaa, "%d", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); strncat(val, tmpaa, tmpjj); } void mychar::str_cat(unsigned long bb) { char tmpaa[100]; sprintf(tmpaa, "%ld", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); strncat(val, tmpaa, tmpjj); } void mychar::str_cat(float bb) { char tmpaa[100]; sprintf(tmpaa, "%f", bb); unsigned long tmpjj = strlen(tmpaa), tmpii = strlen(val); val = (char *) my_realloc(val, tmpii + tmpjj); strncat(val, tmpaa, tmpjj); } mychar operator+ (const mychar & lhs, const mychar & rhs) { /*******************************************************/ // Note : For adding two char strings, first cast mychar // as in - //aa = (mychar) "alkja " + " 99djd " ; /*******************************************************/ mychar tmp(lhs); tmp.str_cat(rhs.val); return(tmp); /* if (mychar::global_mychar == NULL) { mychar::global_mychar = new mychar; mychar::global_mychar->str_cpy(lhs.val); mychar::global_mychar->str_cat(rhs.val); //return *mychar::global_mychar; return mychar(mychar::global_mychar->val); } */ /* else if (mychar::global_mychar1 == NULL) { debug_("1)global", "ok" ); mychar::global_mychar1 = new mychar; mychar::global_mychar1->str_cpy(lhs.val); mychar::global_mychar1->str_cat(rhs.val); return *mychar::global_mychar1; } */ /* else { fprintf(stderr, "\nError: cannot alloc global_mychar\n"); exit(-1); } */ /* mychar *aa = new mychar; aa->str_cpy(lhs.val); aa->str_cat(rhs.val); return *aa; */ } mychar mychar::operator+ (const mychar & rhs) { mychar tmp(*this); tmp.str_cat(rhs.val); debug_("rhs.val in operator+", rhs.val ); debug_("tmp.val in operator+", tmp.val ); return (tmp); } // Using reference will be faster in = operator mychar& mychar:: operator= ( const mychar& rhs ) { if (& rhs == this) { debug_("Fatal Error: In operator(=). rhs is == to 'this pointer'!!", "ok" ); return *this; } this->str_cpy(rhs.val); debug_("rhs value", rhs.val ); // Free global vars memory //free_glob(& mychar::global_mychar); //if (mychar::global_mychar == NULL) //fprintf(stderr, "\nglobal_mychar is freed!\n"); //return (mychar(*this)); return *this; } // Using reference will be faster in = operator mychar& mychar::operator+= (const mychar & rhs) { /*******************************************************/ // Note : For adding two char strings, first cast mychar // as in - //aa += (mychar) "cccc" + "dddd"; /*******************************************************/ if (& rhs == this) { debug_("Fatal error: In operator+= rhs is equals 'this' ptr", "ok"); return *this; } this->str_cat(rhs.val); return *this; //return (mychar(*this)); } bool mychar::operator== (const mychar & rhs) { return(equalto(rhs.val)); } bool mychar::operator== (const char *rhs) { return(equalto(rhs)); } bool mychar::operator!= (const mychar & rhs) { return(equalto(rhs.val, true)); } bool mychar::operator!= (const char *rhs) { return(equalto(rhs, true)); } ______________________________________________________________________ 15. ÷ºÎ D my_malloc.cpp Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ //Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** /* ** In your main() function put these lines - char p_name[1024]; sprintf(p_name, "PROGRAM_NAME=%s", argv[0]); putenv(p_name); print_total_memsize(); // in the beginning ...... ...... print_total_memsize(); // in the end */ #include #include // for c++ -- malloc, alloc etc... #include // malloc, alloc.. #include // strftime, localtime, ... #include // strftime, localtime, ... see file include/g++/stl_list.h //#include // debug_("a", a); debug2_("a", a, true); #include "my_malloc.h" const short SAFE_MEM = 10; const short DATE_MAX_SIZE = 200; const short MALLOC = 1; const short REALLOC = 2; const short VOID_TYPE = 1; const short CHAR_TYPE = 2; const short SHORT_TYPE = 3; const short INT_TYPE = 4; const short LONG_TYPE = 5; const short FLOAT_TYPE = 6; const short DOUBLE_TYPE = 7; const char LOG_FILE[30] = "memory_error.log"; // Uncomment this line to debug total mem size allocated... //#define DEBUG_MEM "debug_memory_sizes_allocated" static void raise_error_exit(short mtype, short datatype, char fname[], int lineno); #ifdef DEBUG class MemCheck { public: MemCheck(void *aptr, size_t amem_size, char fname[], int lineno); void *ptr; size_t mem_size; static list mcH; // list head static unsigned long total_memsize; // total memory allocated }; // Global variables .... list MemCheck::mcH; unsigned long MemCheck::total_memsize = 0; MemCheck::MemCheck(void *aptr, size_t amem_size, char fname[], int lineno) { char func_name[100]; FILE *ferr = NULL; sprintf(func_name, "MemCheck() - File: %s Line: %d", fname, lineno); ferr = fopen(LOG_FILE, "a"); if (ferr == NULL) { fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE); fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE); #ifdef DEBUG_MEM exit(-1); #else return; #endif } // Search if the pointer already exists in the list... bool does_exist = false; list::iterator iter1; // see file include/g++/stl_list.h //fprintf(ferr, "\n%s Before checking.. !!\n", func_name); if (MemCheck::mcH.empty() == true ) { //fprintf(ferr, "\n%s List is empty!!\n", func_name); } for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++) { if (iter1 == NULL) { fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name); break; } if ( ((*iter1).ptr) == aptr) { does_exist = true; fprintf(ferr, "\n%s Already exists!!\n", func_name); fprintf(ferr, "\n%s Fatal Error exiting now ....!!\n", func_name); #ifdef DEBUG_MEM exit(-1); //------------------------------------------------------------------>>> #else return; #endif // Now change the mem size to new values... // For total size - Remove old size and add new size //fprintf(ferr, "\n%s total_memsize = %lu\n", func_name, (*iter1).total_memsize); //fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size); //fprintf(ferr, "\n%s amem_size = %u\n", func_name, amem_size); (*iter1).total_memsize = (*iter1).total_memsize + amem_size; if ((*iter1).total_memsize > 0 ) { if ((*iter1).total_memsize >= (*iter1).mem_size ) (*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size; else { fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name); fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize); fprintf(ferr, "\n%s mem_size = %u", func_name, (*iter1).mem_size); fprintf(ferr, "\n%s amem_size = %u\n", func_name, amem_size); } } (*iter1).mem_size = amem_size; } } // The pointer aptr does not exist in the list, so append it now... if (does_exist == false) { //fprintf(ferr, "\n%s aptr Not found\n", func_name); ptr = aptr; mem_size = amem_size; MemCheck::total_memsize += amem_size; MemCheck::mcH.insert(MemCheck::mcH.end(), *this); } fclose(ferr); } static inline void call_check(void *aa, size_t tmpii, char fname[], int lineno) { MemCheck bb(aa, tmpii, fname, lineno); if (& bb); // a dummy statement to avoid compiler warning msg. } static inline void remove_ptr(void *aa, char fname[], int lineno) { char func_name[100]; if (aa == NULL) return; sprintf(func_name, "remove_ptr() - File: %s Line: %d", fname, lineno); FILE *ferr = NULL; ferr = fopen(LOG_FILE, "a"); if (ferr == NULL) { fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE); fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE); #ifdef DEBUG_MEM exit(-1); #else return; #endif } bool does_exist = false; if (MemCheck::mcH.empty() == true) { //fprintf(ferr, "\n%s List is empty!!\n", func_name); //fclose(ferr); //return; } list::iterator iter1; // see file include/g++/stl_list.h for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++) { if (iter1 == NULL) { fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name); break; } if ( ((*iter1).ptr) == aa) { does_exist = true; // Now change the mem size to new values... // For total size - Remove old size //fprintf(ferr, "\n%s total_memsize = %lu\n", func_name, (*iter1).total_memsize); //fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size); if ((*iter1).total_memsize > 0 ) { if ((*iter1).total_memsize >= (*iter1).mem_size ) (*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size; else { fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name); fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize); fprintf(ferr, "\n%s mem_size = %u\n", func_name, (*iter1).mem_size); } } MemCheck::mcH.erase(iter1); break; // must break to avoid infinite looping } } if (does_exist == false) { //fprintf(ferr, "\n%s Fatal Error: - You did not allocate memory!! \n", func_name); //fprintf(ferr, "\n%s The value passed is %s\n", func_name, (char *) aa); } else //fprintf(ferr, "\n%s found\n", func_name); fclose(ferr); } static inline void call_free_check(void *aa, char *fname, int lineno) { char func_name[100]; sprintf(func_name, "call_free_check() - File: %s Line: %d", fname, lineno); FILE *ferr = NULL; ferr = fopen(LOG_FILE, "a"); if (ferr == NULL) { fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE); fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE); #ifdef DEBUG_MEM exit(-1); #else return; #endif } bool does_exist = false; list::iterator iter1; // see file include/g++/stl_list.h for (iter1 = MemCheck::mcH.begin(); iter1 != MemCheck::mcH.end(); iter1++) { if (iter1 == NULL) { fprintf(ferr, "\n%s Iterator iter1 is NULL!!\n", func_name); break; } if ( ((*iter1).ptr) == aa) { does_exist = true; //fprintf(ferr, "\n%s iter1.mem_size = %u\n", func_name, (*iter1).mem_size); //fprintf(ferr, "\n%s Total memory allocated = %lu\n", func_name, (*iter1).total_memsize); if ((*iter1).total_memsize > 0 ) { if ((*iter1).total_memsize >= (*iter1).mem_size ) (*iter1).total_memsize = (*iter1).total_memsize - (*iter1).mem_size; else { fprintf(ferr, "\n\n%s total_memsize is less than mem_size!!", func_name); fprintf(ferr, "\n%s total_memsize = %lu", func_name, (*iter1).total_memsize); fprintf(ferr, "\n%s mem_size = %u", func_name, (*iter1).mem_size); } } MemCheck::mcH.erase(iter1); break; // must break to avoid infinite looping } } if (does_exist == false) { fprintf(ferr, "\n%s Fatal Error: free() - You did not allocate memory!!\n", func_name); //fprintf(ferr, "\n%s The value passed is %s\n", func_name, (char *) aa); fclose(ferr); #ifdef DEBUG_MEM exit(-1); #else return; #endif } else { //fprintf(ferr, "\n%s found\n", func_name); } fclose(ferr); } void local_print_total_memsize(char *fname, int lineno) { char func_name[100]; sprintf(func_name, "local_print_total_memsize() - %s Line: %d", fname, lineno); FILE *ferr = NULL; ferr = fopen(LOG_FILE, "a"); if (ferr == NULL) { fprintf(stdout, "\nWarning: Cannot open file %s\n", LOG_FILE); fprintf(stderr, "\nWarning: Cannot open file %s\n", LOG_FILE); #ifdef DEBUG_MEM exit(-1); #else return; #endif } fprintf(ferr, "\n%s Total memory MemCheck::total_memsize = %lu\n", func_name, MemCheck::total_memsize); fclose(ferr); } #else //------------> DEBUG void local_print_total_memsize(char *fname, int lineno) { // This function is available whether debug or no-debug... } #endif // DEBUG void local_my_free(void *aa, char fname[], int lineno) { if (aa == NULL) return; call_free_check(aa, fname, lineno); free(aa); aa = NULL; } // size_t is type-defed unsigned long void *local_my_malloc(size_t size, char fname[], int lineno) { size_t tmpii = size + SAFE_MEM; void *aa = NULL; aa = (void *) malloc(tmpii); if (aa == NULL) raise_error_exit(MALLOC, VOID_TYPE, fname, lineno); memset(aa, 0, tmpii); call_check(aa, tmpii, fname, lineno); return aa; } // size_t is type-defed unsigned long char *local_my_realloc(char *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpjj = 0; if (aa) // aa != NULL tmpjj = strlen(aa); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (char) * (tmpqq); aa = (char *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); aa[tmpqq-1] = 0; unsigned long kk = tmpjj; if (tmpjj > tmpqq) kk = tmpqq; for ( ; kk < tmpqq; kk++) aa[kk] = 0; call_check(aa, tmpii, fname, lineno); return aa; } // size_t is type-defed unsigned long short *local_my_realloc(short *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (short) * (tmpqq); aa = (short *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); // Not for numbers!! aa[tmpqq-1] = 0; call_check(aa, tmpii, fname, lineno); return aa; } // size_t is type-defed unsigned long int *local_my_realloc(int *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (int) * (tmpqq); aa = (int *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); // Not for numbers!! aa[tmpqq-1] = 0; call_check(aa, tmpii, fname, lineno); return aa; } // size_t is type-defed unsigned long long *local_my_realloc(long *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (long) * (tmpqq); aa = (long *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); // Not for numbers!! aa[tmpqq-1] = 0; call_check(aa, tmpii, fname, lineno); return aa; } // size_t is type-defed unsigned long float *local_my_realloc(float *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (float) * (tmpqq); aa = (float *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); // Not for numbers!! aa[tmpqq-1] = 0; call_check(aa, tmpii, fname, lineno); return aa; } // size_t is type-defed unsigned long double *local_my_realloc(double *aa, size_t size, char fname[], int lineno) { remove_ptr(aa, fname, lineno); unsigned long tmpqq = size + SAFE_MEM; size_t tmpii = sizeof (double) * (tmpqq); aa = (double *) realloc(aa, tmpii); if (aa == NULL) raise_error_exit(REALLOC, CHAR_TYPE, fname, lineno); // do not memset!! memset(aa, 0, tmpii); // Not for numbers!! aa[tmpqq-1] = 0; call_check(aa, tmpii, fname, lineno); return aa; } static void raise_error_exit(short mtype, short datatype, char fname[], int lineno) { if (mtype == MALLOC) { fprintf(stdout, "\nFatal Error: malloc() failed!!"); fprintf(stderr, "\nFatal Error: malloc() failed!!"); } else if (mtype == REALLOC) { fprintf(stdout, "\nFatal Error: realloc() failed!!"); fprintf(stderr, "\nFatal Error: realloc() failed!!"); } else { fprintf(stdout, "\nFatal Error: mtype not supplied!!"); fprintf(stderr, "\nFatal Error: mtype not supplied!!"); exit(-1); } // Get current date-time and print time stamp in error file... char date_str[DATE_MAX_SIZE + SAFE_MEM]; time_t tt; tt = time(NULL); struct tm *ct = NULL; ct = localtime(& tt); // time() in secs since Epoch 1 Jan 1970 if (ct == NULL) { fprintf(stdout, "\nWarning: Could not find the local time, localtime() failed\n"); fprintf(stderr, "\nWarning: Could not find the local time, localtime() failed\n"); } else strftime(date_str, DATE_MAX_SIZE , "%C", ct); FILE *ferr = NULL; char filename[100]; strcpy(filename, LOG_FILE); ferr = fopen(filename, "a"); if (ferr == NULL) { fprintf(stdout, "\nWarning: Cannot open file %s\n", filename); fprintf(stderr, "\nWarning: Cannot open file %s\n", filename); } else { // ************************************************** // ******* Do putenv in the main() function ********* // char p_name[1024]; // sprintf(p_name, "PROGRAM_NAME=%s", argv[0]); // putenv(p_name); // ************************************************** char program_name[200+SAFE_MEM]; if (getenv("PROGRAM_NAME") == NULL) { fprintf(ferr, "\n%sWarning: You did not putenv() PROGRAM_NAME env variable in main() function\n", date_str); program_name[0] = 0; } else strncpy(program_name, getenv("PROGRAM_NAME"), 200); if (mtype == MALLOC) fprintf(ferr, "\n%s: %s - Fatal Error - my_malloc() failed.", date_str, program_name); else if (mtype == REALLOC) { fprintf(ferr, "\n%s: %s - Fatal Error - my_realloc() failed.", date_str, program_name); char dtype[50]; switch(datatype) { case VOID_TYPE: strcpy(dtype, "char*"); break; case CHAR_TYPE: strcpy(dtype, "char*"); break; case SHORT_TYPE: strcpy(dtype, "char*"); break; case INT_TYPE: strcpy(dtype, "char*"); break; case LONG_TYPE: strcpy(dtype, "char*"); break; case FLOAT_TYPE: strcpy(dtype, "char*"); break; case DOUBLE_TYPE: strcpy(dtype, "char*"); break; default: strcpy(dtype, "none*"); break; } fprintf(ferr, "\n%s %s - Fatal Error: %s realloc() failed!!", date_str, program_name, dtype); } fprintf(ferr, "\n%s %s - Very severe error condition. Exiting application now....", date_str, program_name); fclose(ferr); } exit(-1); } ______________________________________________________________________ 16. ÷ºÎ E my_malloc.h Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ //Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** /* ** In your main() function put - char p_name[1024]; sprintf(p_name, "PROGRAM_NAME=%s", argv[0]); putenv(p_name); print_total_memsize(); // in the beginning ...... ...... print_total_memsize(); // in the end */ /* Use zap instead of delete as this will be very clean!! ** Use do while to make it robust and bullet-proof macro */ #define zap(x) do { if (x) { delete(x); x = 0; } } while (0) void *local_my_malloc(size_t size, char fname[], int lineno); char *local_my_realloc(char *aa, size_t size, char fname[], int lineno); short *local_my_realloc(short *aa, size_t size, char fname[], int lineno); void local_my_free(void *aa, char fname[], int lineno); void local_print_total_memsize(char fname[], int lineno); #define my_free(NM) (void) (local_my_free(NM, __FILE__, __LINE__)) #define my_malloc(SZ) (local_my_malloc(SZ, __FILE__, __LINE__)) #define my_realloc(NM, SZ) (local_my_realloc(NM, SZ, __FILE__, __LINE__)) #define print_total_memsize() (void) (local_print_total_memsize(__FILE__, __LINE__)) #ifdef DEBUG //------------> DEBUG #else //------------> DEBUG #define call_check(AA, BB, CC, DD) ((void) 0) #define call_free_check(AA, BB, CC) ((void) 0) #define remove_ptr(AA, CC, DD) ((void) 0) #endif //------------> DEBUG ______________________________________________________________________ 17. ÷ºÎ F debug.h Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ //Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** #define print_log(AA, BB, CC, DD, EE) ((void) 0) #ifdef DEBUG #include #include //#include // assert() macro which is also used for debugging const bool LOG_YES = true; // print output to log file const bool LOG_NO = false; // Do not print output to log file // Debugging code // Use debug2_ to output result to a log file #define debug_(NM, VL) (void) ( local_dbg(NM, VL, __FILE__, __LINE__) ) #define debug2_(NM, VL, LOG_FILE) (void) ( local_dbg(NM, VL, __FILE__, __LINE__, LOG_FILE) ) void local_dbg(char name[], char value[], char fname[], int lineno, bool logfile= false); void local_dbg(char name[], string value, char fname[], int lineno, bool logfile= false); void local_dbg(char name[], int value, char fname[], int lineno, bool logfile= false); void local_dbg(char name[], unsigned long value, char fname[], int lineno, bool logfile= false); void local_dbg(char name[], float value, char fname[], int lineno, bool logfile= false); void local_dbg(char name[], double value, char fname[], int lineno, bool logfile= false); #else //--------> else #define debug_(NM, VL) ((void) 0) #define debug2_(NM, VL, LOG_FILE) ((void) 0) #endif // DEBUG ______________________________________________________________________ 18. ÷ºÎ G debug.cpp Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ //***************************************************************** //ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ //Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. //ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com //***************************************************************** #ifdef DEBUG // ONLY if DEBUG is defined then these functions below are needed #include "debug.h" //#include "log.h" // Variable value[] can be char, string, int, unsigned long, float, etc... void local_dbg(char name[], char value[], char fname[], int lineno, bool logfile) { if (value == NULL) return; if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %s\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], string value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %s\n", fname, lineno, name, value.c_str()); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value.c_str() << endl; } void local_dbg(char name[], int value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %d\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], unsigned int value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %u\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], long value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %d\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], unsigned long value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %u\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], short value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %d\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], unsigned short value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %u\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], float value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %f\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } void local_dbg(char name[], double value, char fname[], int lineno, bool logfile) { if (logfile == true) print_log("\nDebug %s : Line: %d %s is = %f\n", fname, lineno, name, value); else cout << "\nDebug " << fname << ": Line: " << lineno << " " << name << " is = " << value << endl; } // You add many more here - value can be a class, ENUM, datetime, etc... #endif // DEBUG ______________________________________________________________________ 19. ÷ºÎ H Makefile Download mychar ¿¡¼­ ¸ðµç ÇÁ·Î±×·¥µéÀ» ÇϳªÀÇ tar.gz È­ÀÏ·Î ´Ù¿î·Îµå¹ÞÀ» ¼ö ÀÖ´Ù. ÀÌ È­ÀÏÀ» ¹ÞÀ¸·Á¸é À¥ºê¶ó¿ìÀú¿¡¼­ ÀÌ È­ÀÏÀ» 'Text' ŸÀÔÀ¸·Î ÀúÀåÇÑ´Ù. ______________________________________________________________________ #//***************************************************************** #//ÀúÀÛ±ÇÀº GNU/GPL ¿¡ ÀÖÁö¸¸ ÀúÀÚÀÇ À̸§°ú À̸ÞÀÏÀº ¸ðµç º¹»çº»¿¡ #//Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù. #//ÀúÀÚ: Al Dev À̸ÞÀÏ: alavoor@yahoo.com #//***************************************************************** .SUFFIXES: .pc .cpp .c .o CC=gcc CXX=g++ MAKEMAKE=mm LIBRARY=libmychar.a DEST=/home/myname/lib # To build the library, and main test program uncomment line below :- #MYCFLAGS=-O -Wall # To test without debug trace uncomment line below:- #MYCFLAGS=-g3 -Wall # To enable 'full debug ' tracing uncomment line below:- MYCFLAGS=-g3 -DDEBUG -Wall #PURIFY=purify -best-effort SRCS=my_malloc.cpp mychar.cpp debug.cpp example_mychar.cpp HDR=my_malloc.h mychar.h debug.h OBJS=my_malloc.o mychar.o debug.o example_mychar.o EXE=mychar # For generating makefile dependencies.. SHELL=/bin/sh CPPFLAGS=$(MYCFLAGS) $(OS_DEFINES) CFLAGS=$(MYCFLAGS) $(OS_DEFINES) # # If the libmychar.a is in the current # directory then use -L. (dash L dot) MYLIBDIR=-L$(MY_DIR)/libmy -L. ALLLDFLAGS= $(LDFLAGS) $(MYLIBDIR) COMMONLIBS=-lstdc++ -lm MYLIBS=-lmychar LIBS=$(COMMONLIBS) $(MYLIBS) all: $(LIBRARY) $(EXE) $(MAKEMAKE): @rm -f $(MAKEMAKE) $(PURIFY) $(CXX) -M $(INCLUDE) $(CPPFLAGS) *.cpp > $(MAKEMAKE) $(EXE): $(OBJS) @echo "Creating a executable " $(PURIFY) $(CC) -o $(EXE) $(OBJS) $(ALLLDFLAGS) $(LIBS) $(LIBRARY): $(OBJS) @echo "\n***********************************************" @echo " Loading $(LIBRARY) ... to $(DEST)" @echo "***********************************************" @ar cru $(LIBRARY) $(OBJS) @echo "\n " .cpp.o: $(SRCS) $(HDR) # @echo "Creating a object files from " $*.cpp " files " $(PURIFY) $(CXX) -c $(INCLUDE) $(CPPFLAGS) $*.cpp .c.o: $(SRCS) $(HDR) # @echo "Creating a object files from " $*.c " files " $(PURIFY) $(CC) -c $(INCLUDE) $(CFLAGS) $*.c clean: rm -f *.o *.log *~ *.log.old *.pid core err a.out lib*.a afiedt.buf rm -f $(EXE) rm -f $(MAKEMAKE) #%.d: %.c # @echo "Generating the dependency file *.d from *.c" # $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@/g'\'' > $@' #%.d: %.cpp # @echo "Generating the dependency file *.d from *.cpp" # $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< | sed '\''s/$*.o/& $@/g'\'' > $@' # Must include all the c flags for -M option #$(MAKEMAKE): # @echo "Generating the dependency file *.d from *.cpp" # $(CXX) -M $(INCLUDE) $(CPPFLAGS) *.cpp > $(MAKEMAKE) include $(MAKEMAKE) #include $(SRCS:.cpp=.d) #include $(SRCS:.c=.d) ______________________________________________________________________