C언어 파일 입출력 너무 어렵네요ㅠ.ㅠ

newbboy의 이미지

아직 개념이 덜 잡혀서 최대한 짜깁기 하면서 이해하려고 노력하고 있는데
잘 안되네요..

7M이 넘는 txt파일을 불러와서 처리해야 하기 때문에 동적할당으로 배열을 최대한 크게
잡았습니다. 처리해야할 것이 10만개를 훨씬 넘습니다;;

파일에서 빈칸,탭,개행문자로 구분해서 한 단어라고 하는 것을 추출합니다.
그리고 그 단어에 알파벳 이외의 문자가 있으면 그냥 버리고 전부 알파벳으로만 이루어진
단어라면 그 단어를 배열에 차곡 차곡 저장하는것 입니다.

한번 아래와 같이 구현해보았는데 words[numwords++] = strdup(word); 이부분에서
포인터 값이 잘 안맞는지 char * 에서 char 로 변환할 수 없다는 에러메세지가 뜹니다.

도움 부탁드립니다!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
 
#define ARRAY_SIZE 10000
 
int main()
{
	char* word = (char*)malloc(sizeof(char)*ARRAY_SIZE);
	char* words = (char*)malloc(sizeof(char)*ARRAY_SIZE);
 
	//char *words[ARRAY_SIZE];
    //char word[ARRAY_SIZE];
	int numwords = 0;
 
	FILE *fp;
 
	int i=0,damn=0,len=0;
 
	fp = fopen("document.txt","r");
 
    while( fscanf(fp, "%s", word) != EOF )
    {
		len=strlen(word);
		for(i=0;i<len;i++)
		{
			if(!isalpha(word[i]))
				damn++;
		}
		if(damn==0)
		{
			words[numwords++] = strdup(word);
			damn=0;
		}
	}
 
	for(i=0;i<numwords;i++)
        printf("%s\n", words[i]);
 
	free(word);
	free(words);
 
}
hiseob의 이미지

(글삭제 ^^;;) 본인의 무지함이 적나라하게 드러났군요.;;

gurumong의 이미지

words 선언이 잘못되었네요
의도대로 하실려면 아래와 같이 char*을 원소로 하는 배열로 선언을 하셔야되요
char* words[ARRAY_SIZE] = {}; // 포인터들을 null 로 초기화

newbboy의 이미지

words에 배열 크기를 선언해 버리면 오버플로우가 나서 malloc 선언 한 것이라서요..
알려주신 배열 선언을 하고 크기가 작은 텍스트 파일을 연 상태에서
 
len=strlen(word);
	for(i=0;i<len;i++)
	{
		if(!isalpha(word[i]))
		damn++;
	}
	if(damn==0)
	{
		words[numwords++] = strdup(word);
		damn=0;
	}
이 부분을
words[numwords++] = strdup(word);
만 남겨두고 실행해 보면 잘 뜨구요, 다시 7M짜리 파일을 열면 오버플로가 나버립니다ㅠㅠ

richjaff의 이미지

우선 저기서 오버플로우가 나는 이유는

#define ARRAY_SIZE 10000
 
char* word = (char*)malloc(sizeof(char)*ARRAY_SIZE);
char* words = (char*)malloc(sizeof(char)*ARRAY_SIZE); // 여기서 동적할당을 쓰고 있지만, 사이즈 자체를 이렇게
//가변적이지 않은 ARRAY_SIZE 사이즈만큼 고정시키고 있으니, 오버플로우가 일어날 수 밖에요...

그리고 words를 소스코드에서 사용하는 방식을 보아하니, 문자열의 목록을 담기위해서 선언하신것 같은데...
한마디로 char포인터형을 담아내기 위한 배열로 사용하고 계시니 아래처럼 바꿔주셔야합니다.

char** words = (char**)malloc((포인터크기)*ARRAY_SIZE);

마지막으로... C언어 대신
C++ 표준라이브러리로 아래처럼 편리하고 간결하게 구현할 수 있습니다.
7메가짜리 파일도 문제없이 열리네요.

소스코드를 보니 읽어들인 텍스트 파일내 각 라인의 문자열상에
알파벳이 없는 문자열들만 리스트화해서 마지막에 출력하시려고 하시는것 같은데, 맞나요?
그렇다면, 문자열의 갯수는 정해진 갯수보다 충분히 커질 수 있기 때문에,
이런 가변적인 요소를 쉽게 해결하기 위해서는 고정 배열이나 위와 같은 방법을쓰는 것 보다는
STL 컨테이너를 쓰는게 훨씬 효율적입니다.
라인의 문자열 자체도 가변적이기 때문에, char 배열을 쓰거나, char 동적배열을 쓸바에는
string 객체를 쓰는게 낫구요.

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <windows.h>
#include <stdlib.h>
#include <queue>
 
using namespace std;
 
int main(int argc, char *argv[])
{	
	ifstream InputFile("document.txt");
	if(!InputFile){
		cout << "Open Error!" << endl;
		return 0;
	}
	string line;
	int length = 0;
	char* buff = NULL;
	queue<string> StrList;
	while(getline(InputFile, line) != NULL){
		bool existalpha = false;
		length = line.size();
		buff = (char*)line.c_str();
		for(int i=0; i<length; i++){
			if(isalpha(buff[i])){
				existalpha = true;
				break;
			}
		}
		if(!existalpha){
			StrList.push(line);
		}
	}
 
	while(!StrList.empty()){
		cout << StrList.front() << endl;
		StrList.pop();
	}
 
	InputFile.close();
 
	system("pause");	
	return 0;
}
newbboy의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
 
#define ARRAY_SIZE 100000
 
int main()
{
	char* word = (char*)malloc(sizeof(char)*ARRAY_SIZE);
	char** words= (char**)malloc(sizeof(char)*ARRAY_SIZE);
 
	int numwords = 0;
 
	FILE *fp;
 
	int i=0,damn=0,len=0,j=0;
	char* buff = NULL;
 
	fp = fopen("test.txt","r");
 
    while( fscanf(fp, "%s", word) != EOF )
    {
		len=strlen(word);
		buff = (char*)word.c_str();
 
		for(i=0;i<len;i++)
		{
			if(isalpha(buff[i]) != 0 )
			{
				damn=1;
				break;
			}
		}
		if(damn==0)
		{
			words[numwords++] = strdup(word);
			damn=0;
		}
	}
 
	for(i=0;i<numwords;i++)
	{
		printf("%s\n",word[i]);
	}
        free(word);
}

이렇게 해보았는데 buff = (char*)word.c_str(); 요 부분에서
" error C2228: '.c_str' 왼쪽에는 클래스/구조체/공용 구조체가 있어야 합니다.
'char *' 형식입니다." 라는 오류가 떠버리네요ㅠ.ㅠ

아 그리고 논리적 오류가 있었는데, 공백/탭/개행 문자로 구분된 한 string을 단어라고 하고
그 단어가 알파뱃 의외의 문자 - , . ' 등이 들어가 있으면 그냥 버리고 그게 아니면 배열에
삽입하는겁니다^^

그런 후에 이제 사전순으로 따로 배열을 해야되서요ㅎㅎ

raymundo의 이미지

클 모 사이트에서도 봤던 것 같은데 여기서 뵙는군요 :-)

5시에 작성하신 리플의 코드는 C와 C++가 엄하게 섞였네요. word 는 char * 타입일 뿐이니 뒤에 .c_str 이런 필드를 적을 수 없죠. 위에 richjaff님 코드에서는 line 이 string 클래스라서 가능한 거고...

새로 올리신 코드는 그 외의 부분은 제가 안 봐서 모르겠고, 처음 코드에서 보면요..

처음에 words 를 고정된 배열로 했던 코드도 7MB 정도를 다루는 데는 괜찮은 것 같은데요?

char *words[ARRAY_SIZE];
char word[ARRAY_SIZE];

여기서 word 는 매번 scanf 로 읽는 한 단어들을 임시로 넣을 공간이니 굳이 ARRAY_SIZE 만큼의 공간은 필요가 없고, 텍스트 파일 내에서 가장 긴 단어의 길이보다 길기만 하면 되겠죠. 수십~백 정도만 잡아도 될 것 같고,

words 의 크기가 문제인데, 영어텍스트 한 문단을 계속 복사해서 7.4MB 짜리 텍스트를 만들었더니 단어 갯수가 132만개 정도 되더군요. 제가 리눅스 시스템에서 gcc 로 컴파일해보면 ARRAY_SIZE 를 2,000,000 정도로 잡으니 너끈하더군요.

그리고 damn 값을 0으로 다시 세팅하는 문장은 if 문 바깥쪽으로 빼셔야겠죠. 안 그러면 한 번 1이 되면 다시는 0이 되지 않으니 이후의 단어들은 죄다 저장되지 않습니다.

배열 말고 malloc 으로 words 를 잡는다면, richjaff님 말씀처럼, 문자열의 목록 = char 의 포인터의 목록이니까 char * 가 아니라 char ** 여야 하고

    char** words = (char**)malloc(sizeof(char *)*ARRAY_SIZE);

역시 ARRAY_SIZE는 2백만 정도로 잡으니 무리없이 읽어서 출력하는 걸 확인했습니다.

도움이 되면 좋겠네요.

P.S. 별개의 얘기지만, 문장 마지막 단어들이 뒤에 마침표 붙는 것 때문에 저장되지 못하고 스킵되더군요. 아마 그 처리도 해주셔야 할 듯?

좋은 하루 되세요!

newbboy의 이미지

아... 소스를 보고 짜깁기를 하다보니 또 제대로 되지가 않는군요.. C++ 언어를 섞어 쓴걸
이제야 알았네요;;;

   while( fscanf(fp, "%s", word) != EOF )
    {
		len=strlen(word);
 
		for(i=0;i<len;i++)
		{
			if(isalpha(word[i]) != 0 )
			{
				damn=1;
				break;
			}
		}
		if(damn==0)
		{
			words[numwords++] = strdup(word);
			damn=0;
		}
	}
 
	for(i=0;i<numwords;i++)
	{
		printf("%s\n",word[i]);
	}

대충 핵심은 이정도 인데, isalpha(word[i]) 이 부분에서 살짝 말썽을 피우네요..
저렇게 직접 접근해서 배열의 값을 가져오면 안되는건지 모르겠습니다..

그리고 ARRAY_SIZE를 2000000으로 두고 돌려버리니 스택 오버플로가 생기고
200000으로 하니 그냥 프로그램이 아무것도 안뜨네요.. 실행은 되긴 되는데;;

제가 VMWare상에서 램을 약 1GB로 잡아두었는데 이 이유일까요?;;

raymundo의 이미지

isalpha()쪽은 제가 할 때는 전혀 문제의 소지가 없었는데... word 는 윗 글에서도 말했듯이 굳이 클 필요가 없으니 char word[100] 정도만 잡고 해 보시지요. 아니면 그렇게 했는데도 isalpha 쪽에서 문제가 되던가요?

좋은 하루 되세요!

newbboy의 이미지

char word[100]으로 잡아주고,

words는 200000으로 잡아주면 실행은 되고 결과는 없고
words는 2000000으로 잡아주면 오버플로가 나네요.. 디버깅 포인트도 없구요;

다시 디버깅 포인트 잡아서 차례 차례 내려가니

단어를 배열에 넣는 부분에서
words[numwords++] = strdup(word);
words[numwords++]이 이 잘못 되었다고 뜨네요;;

raymundo의 이미지

음 그럼 시스템마다 배열의 원소 갯수의 한계가 다른가보네요.. 아니면 컴파일러 옵션으로 지정이 가능할런지...

그럼 처음 적으신 코드에서 malloc 을 사용한 경우도 2백만이면 문제가 되던가요? 텍스트 문서의 단어 갯수를 대강 어림잡아서 최소한도로 사용하게 해보던가...

그도 안 되면 아예 접근 방법을 좀 바꿔야 할지도... 저는 더는 모르겠네요 ^^;

좋은 하루 되세요!

richjaff의 이미지

흠... 기본기가 많이 부족하신것 같네요.
코드내에서 하나하나 잘못된 부분을 찝어드리겠습니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
 
#define ARRAY_SIZE 10000
 
int main()
{
	char* word = (char*)malloc(sizeof(char)*ARRAY_SIZE);
	char* words = (char*)malloc(sizeof(char)*ARRAY_SIZE); // 일단 이게 문제입니다.
	// 여기서 words는 char 포인터에 의한 , char 포인터를 위한 배열이 되어야합니다.
	// 그러면 아래처럼 바꿔줘야겠죠.
	char** words = (char**)malloc(sizeof(char*)*ARRAY_SIZE);
	// 1.char*를 가리키는 포인터형이므로 char**형으로 선언해야한다.
	// 2.동적할당을 할때, 여기서 sizeof(char*)과 sizeof(char)는 전혀 다른 의미가 된다.
	// char타입은 말그대로 -128~127의 값을 가지는 1바이트의 자료형이지만,
	// char*타입은 포인터 타입이므로 32비트 운영체제를 기준으로 4바이트의 값을 가집니다.
	// 님께서 words라는 변수를, 문자열의 주소를 담는 리스트로 쓰고 계시니,
	// char*형을 원소로 가지는 배열 포인터, char**형으로 선언하시고,
	// 동적할당을 할때는, char*타입의 크기(4바이트) X 리스트 사이즈로 할당을 하셔야합니다.
 
 
	int numwords = 0;
 
	FILE *fp;
 
	int i=0,damn=0,len=0;
 
	fp = fopen("document.txt","r");
 
    while( fscanf(fp, "%s", word) != EOF )
    {
		len=strlen(word);
		for(i=0;i<len;i++)
		{
			if(!isalpha(word[i]))
				damn++;
		}
		if(damn==0)
		{
			words[numwords++] = strdup(word); // 그다음 문제점: numwords를 검사하지 않고 그냥 사용하고 있음. 
			//참조 에러의 잠재적인 원인이됨
			damn=0;
		}
	}
 
	for(i=0;i<numwords;i++) // 여기도 마찬가지로써, 참조 에러의 잠재적인 원인이됨.
        printf("%s\n", words[i]);  // words[i]요소의 NULL인가 아닌가의 검사과정없이 그대로 사용하고 있음.
 
	free(word);
	free(words);
 
// 더불어서 파일포인터를 닫아주지 않고 있음.
 
}

상당히 지적사항이 많네요.
그리고 굳이 여기서 동적배열을 쓸 필요가 없을 것 같은데,
라인 문자열 하나당 길이가 5000개가 안되는 조건에 맞는다면,
차라리 아래처럼...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
 
#define ARRAY_SIZE 5000
#define LIST_SIZE	500000
 
int main()
{
	char word[ARRAY_SIZE]={};
	char* words[ LIST_SIZE ]={};
 
	int numwords = 0;
 
	FILE *fp = fopen("document.txt","r");
	if(fp==NULL){
		printf("File Error!\n");
		return 0;
	}
 
	int len=0;
    while( fscanf(fp, "%s", word) != EOF )
    {
		bool damn = true;
		len=strlen(word);
		for(int i=0;i<len;i++)
		{
			if(!isalpha(word[i])){
				damn = false;
				break;
			}
		}
		if(damn)
		{
			if(numwords<LIST_SIZE){	// 버퍼 오버플로우 방지
				words[numwords] = strdup(word); // 여기서 동적할당을 다시 실시해주고 있군요. 
				// 그럼 아래에서 동적할당을 해제하는 구문이 필요합니다.
				numwords++;
			}else{
				printf("리스트의 최대 갯수를 초과하여 문자열 추출을 중단합니다.\n");
				break;
			}
		}
		memset(word,0,sizeof(word));	// 새로 라인을 읽어들일때마다 항상 초기화를 실시해줍니다.
	}
 
	int k=0;
	while(!words[k]&&k<LIST_SIZE){	// 리스트가 NULL이 아닌 동시에 최대 리스트 사이즈이내일때 출력을 실시합니다.
        printf("%s\n", words[k]);
		// 출력후에는 아래처럼 동적할당을 해제시켜주세요.
		free(words[k]);
		k++; // 해제 이후에 다시 인덱스 값증가
	}
 
	fclose(fp);	 // 파일포인터를 닫습니다.
	return 0;
}

-정리하자면,
1.동적할당을 할때에 원소가 무엇이냐에 따라 그에 맞는 할당을 실시해준다.
타입* = (타입*)malloc(sizeof(타입)*원하는크기);
위에서 words는 포인터형을 원소로 가지는 동적배열입니다. 그럼 아래처럼
char** (char**)malloc(sizeof(char*)*MAXIMUMSIZE);
이때, char원소와 char*원소를 가지는 배열의 차이점:
-->char* : 생성되는 크기는 4바이트(주소값의 자료크기는 32비트(win32)) X 배열의크기(100일때) = 400바이트 (배열의 크기는 100)
-->char : 생성되는 크기는 1바이트 X 배열의크기(100일때) = 100바이트, (배열의 크기는 100)
2.버퍼에 인덱스(첨자)를 사용함에 있어서 참조에러가 일어나는지 검사하는 것은 필수입니다.
또한, 버퍼의 인덱스에는 음수값이 들어가서는 안되므로 부호있는 자료형보다는 unsigned형을 쓰는게 안전합니다.
따라서, 적당히 unsigned int형을 쓰면 되겠죠.
또한, words[인덱스]를 사용함에 있어서 인덱스는 0에서 시작하여 (MAXIMUMSIZE-1)만큼의 값에 대해서만 유효합니다.
그러므로 인덱스값을 항상 검사해주세요.
더불어서 words가 가지는 원소인 포인터형 값에 대한 유효성을 반드시 검사하는게 필요합니다.
3.strdup으로 새로 동적할당을 실시하고 있는데, 이에 대해 동적할당을 해제하는 구문이 없습니다.
따라서, 해제하는 과정을 작업이 완료된 이후에 실시해줘야합니다.
또한 파일 포인터도 작업이 끝나면 꼭 닫도록 하시구요.

-마지막으로
C언어를 공부하시면서 문법이나 사용법만 알려고 하실게 아니라,
"예외"사항의 추측, 메모리 차원에서 어떻게 접근이 이루어지는지,
코드의 전체적인 흐름(코드 하나가 실행되고나서, 어떤 결과가 나오고 이어서 어떤 처리로 이루어질지)을
하나하나 추상적으로 생각하면서 코딩하는 습관이 필요합니다.

더 궁금한게 있으면 질문해주세요.

newbboy의 이미지

긴 답글 정말 감사합니다. 앞으로 C에 대해선 더 많이 배워야 겠다는 생각이 듭니다.
말씀해 주신 소스를 이용해 보면 아무 것도 표시 되지 않고 그냥 프로그램이 종료가 되네요..

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 100
 
typedef struct words {
    char * word;//단어
    struct words * next;//next
}Word;
 
void getword(void);
void insert(char *);
void cmp(char *);
void print(void);
 
Word * start=NULL;
 
void main(void)
{
    getword();
}
void getword(void)
{ 
    char ch,buff[MAX];
    int k=0;
    FILE * fp;
    fp=fopen("test.txt","r");
    if(fp==NULL)
    {
        printf("\n\n\t파일이 없습니다!!\n");
        exit(1);
    }
    else
    {  
        while((ch=fgetc(fp))!=EOF)
        {
            if(isalpha((unsigned char)ch))
                buff[k++]=ch;
            else if(ch==' ' || ch=='\n' || ch=='\t')
            {
                if(k)
                {     
                    buff[k]='\0';     
                    cmp(buff);  
                    k=0;    
                }
 
            }
 
           else
 
              k=0;
        }  
    }
    print();
    fclose(fp);
}
void cmp(char * buff)
{
    Word * cur=start;
    if(start==NULL || (strcmp(start->word,buff))>0);
    else
    {         
        while(cur->next!=NULL)
        {
            if(!strcmp(cur->word,buff))
                return;
            cur=cur->next;
        }
        if(!strcmp(cur->word,buff))
            return;
    }
    insert(buff); 
}
 
void insert(char * buff)
{
    Word * temp, * cur=start;  
    temp=(Word*)malloc(sizeof(Word));
    temp->next=NULL;
    temp->word=(char*)malloc(sizeof(strlen(buff))+1);
    strcpy(temp->word,buff);
    if(start==NULL || (strcmp(start->word,temp->word))>=0)
    {
        temp->next=start;
        start=temp;  
    }
    else
    {
        while(cur->next!=NULL)
        {
            if(strcmp(cur->next->word,temp->word)>=0)
            {
                temp->next=cur->next;
                cur->next=temp;
                return;
            }
            cur=cur->next;
        }
        cur->next=temp;
    }
}
 
void print(void)
{
    Word * cur=start;
    int nCnt=0;
    FILE * ptr;
    ptr=fopen("result.txt","w");
    while(cur->next!=NULL)
    {            
        printf("%-15s",cur->word);
        fprintf(ptr,"%-15s",cur->word);
        nCnt++;
        if(!(nCnt%5))
        {
            printf("\n");
            fprintf(ptr,"\n");
        }
        else
        {           
            printf("\t");
            fprintf(ptr,"\t");
        }
        cur=cur->next;
    }
    printf("%-15s",cur->word);
    fprintf(ptr,"%-15s",cur->word);
    fclose(ptr);
}

링크드 리스트로 구현된 이 소스는 잘 작동을 합니다. 그런데 배열로 작성을 해야하니
이걸 다시 옮기던지 아니면 처음부터 다시 소스를 작성해야할텐데 배열은 안되고
링크드 리스트는 되는게 조금 난감하네요ㅠ.ㅠ;

가상 머신이라 그런건지.. 아니면 배열 크기가 문제인건지 계속 되는 오버 플로우 때문에
배열로 하는 것을 건드리기가 어렵군요.. 직접 머리 싸매며 해결해 보아야 겠습니다.

yielding의 이미지

#!/usr/bin/env ruby
 
File.open("document.txt", "r").readlines.each { |line|  
  line.split.each { |word|
    puts word unless word =~ /[1..0]/
  }
}

Life rushes on, we are distracted

Life rushes on, we are distracted

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.