에디터 질문입니다.

nayana의 이미지

학교레포트로 에디터를 하고 있느데..잘안됩니다.

Editing commands : 
C(urrent) line .......... Set the current line 
F(orward) ................ Print the next page 
B(ackward) ............... Print the previous page 
P(rint) lines ........... Print the lines with line numbers 
O(Copy) lines ............ Copy the lines 
A(Paste) line ............ Past the copied ones into the line 
D(elete) lines .......... Delete the lines 
(지정된 lines를 delete하고 delete한 내용을 줄 번호와 함께 프린트한다). 
I(nsert) line .......... Insert the line 
(지정된 line 앞에 첨부한다. 첨부할 내용은 키보드를 통해서 받는다). 
S(ave) filename ........... Save the current content into the file 
The possible form of lines, for example, 
* (all lines) 
3 (a single line) 
3,5,7 (a list of lines) 
5-10 (a range of lines) 
E(xit) ......... Exit program 

제 나름대로 짜봤는데..구현이 잘안됩니다. O,A 명령어를 어케 구현해야할지
막막합니다.
다음은 제가 짠 소스입니다.

#include <stdio.h> 
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/file.h> 
#include <sys/fcntl.h>	 		  /* 파일 모드 정의 */

#define MAX_LINES   100000		  /* 파일의 최대 라인 수 */
#define BUFFER_SIZE 100000		  /* 복사 버퍼 크기 */

char *fileName = NULL;		      /* 파일 이름에 대한 포인터 */
char readBuffer[BUFFER_SIZE];	  /* read버퍼 선언 */
char deletedbuffer[BUFFER_SIZE];  /* 삭제버퍼 선언 */
int  lineStart[MAX_LINES];		  /* 각줄의 옵셋 저장 */
int  fileOffset = 0;	          /* 입력의 현재위치 */
int  lineCount = 0;	              /* 입력 줄의 합 */ 
int  fd;		                  /* 입력의 파일 기술자*/
char lines[30];		              /* 입력받을 라인 변수 선언 */
int  range;

/* 함수 declare */
void CommandLine();
void usageError();
void pass1();
void trackLines( char* buffer, int charsRead );
void processLine( int i );
int  checkline( char* lines );
void savefile();
void Delete ( int num );
void deleteRange( int start,int end ); 
void insert( int i, char str[] ); 

int main ( int argc, char **argv ) 
{

	/* 명령 줄 인수 분석 */
	if ( argc < 2 ) 
	{ 
		usageError( "Usage:editor [filename]" ); 
	//	exit( 1 ); 
	} 
	if ( fileName == NULL ) 
		fileName = argv[1];
	else
	{			
		//usageError(); 
		printf( "fileName 이 NULL 값이 아닙니다.\n" ); 
		exit(1);
	}	

	if ( ( fd = open( argv[1], O_RDWR, 0600 ) ) == -1 ) 
	{ 
		perror( argv[1] ); 	
		exit(1); 
	} 

	CommandLine();

	return 0;
}

/* command 체크*/
void CommandLine() 
{

//	int quit = 0; 
	int i, current = 1, linenum,  charsRead;
	int number;
	int start, end;

	char command[2];
	int  currentline;
	char line[100];
	char savefilename[10];

	pass1();		/* 파일 스캔 */

	printf("\ncommand->");

	while ( command[0] != 'q' ) 
	{		

		scanf("%1s", command); 

		switch ( command[0] ) 
		{

			/* set the currnet line */
			case 'c':
			case 'C':
				printf("라인수를 입력하세요?\t");
				scanf( "%d", &currentline );
				printf( "\n" );
				
				lseek( fd, lineStart[currentline - 1], SEEK_SET );
				printf( "the current line to set: %d\n", currentline );
				printf( "command->");
				break; 

			/* print the next page */
			case 'f':
			case 'F':
				current = currentline - 1;
				for( i = 0; i < 24; i++ )
					processLine( current++ );
				
				printf( "the current line to set: %d\n", current );
				printf( "command->" );
				break;

			/* print the previous page */	
			case 'b':
			case 'B':
				current = currentline - 1;
				for( i = 0; i < 24; i++ )
					processLine( current-- );
				
				printf("the current line to set: %d\n", current);
				printf("command->");
				break;

			/* print the lines with line numbers */
			case 'p':
			case 'P':
				scanf( "%s", lines );
				range = checkline( lines );

				switch( range )
				{
					case 0: 
						for ( i = 0; i < lineCount; i++ ) 
						{
							processLine(i);
						}
						break;
					
					case 1:
						sscanf( lines,"%d-%d", &start, &end ); 
						for( i = start - 1; i < end; i++ )
							processLine( i );
						break;
					
					case 2: 
						sscanf( lines, "%d,%d", &start, &end ); 
						processLine( --start );
						processLine( --end );
						break;
					
					case 3:
						sscanf( lines, "%d", &linenum ); 
						processLine( --linenum );
						break;
				}
				
				printf("\ncommand->"); 
				break; 

			/* copy the lines */
			case 'o':
			case 'O':
				scanf( "%s", lines );
				range = checkline( lines );

				/*			    switch(range){
								case 0: 
								remove(fileName);
								fd = open(fileName, O_CREAT|O_RDWR, 0600);
								lseek(fd, 0L, SEEK_SET);
								charsRead = read(fd, readBuffer, BUFFER_SIZE);
								write(fd, readBuffer, charsRead); 
								break;
								case 1:
								sscanf(lines,"%d-%d",&start,&end); 
								deleteRange(--start, --end); 
								break;
								case 2: 
								sscanf(lines,"%d,%d",&start,&end); 
								Delete(--start);
								pass1();
								Delete(--end);
								pass1();
								break;
								case 3:
								sscanf(lines,"%d",&linenum); 
								Delete(--linenum);
								pass1();
								break;
								}
				 */
				printf("\ncommand->");
				break;

			/* paste the copied ones into the line */
			case 'a':
			case 'A':
				break;

			/* delete the lines */
			case 'd':
			case 'D':
				scanf( "%s", lines );
				range = checkline( lines );

				switch ( range )
				{
					case 0: 
						remove( fileName );
						fd = open( fileName, O_CREAT|O_RDWR, 0600 );
						lseek( fd, 0L, SEEK_SET );
						charsRead = read( fd, readBuffer, BUFFER_SIZE );
						write( fd, readBuffer, charsRead ); 
						break;
					
					case 1:
						sscanf( lines, "%d - %d", &start, &end ); 
						deleteRange( --start, --end ); 
						break;
					
					case 2: 
						sscanf( lines, "%d, %d", &start, &end ); 
						Delete( --start );
						//	pass1();
						Delete( --end );
						pass1();
						break;
					
					case 3:
						sscanf( lines, "%d", &linenum ); 
						Delete( --linenum );
						pass1();
						break;
				}

				charsRead = read( fd, deletedbuffer, BUFFER_SIZE );
				write( 1, deletedbuffer, charsRead );
				write( 1, "\n", 2 ); 

				printf( "\ncommand->" );
				break; 

			/* insert the line */
			case 'i':
			case 'I':
				scanf( "%d", &number );
				printf( "input content to append=>" );
				scanf( "%s", line );
				insert( number, line );
				printf( "\ncommand->" );
				break;

			/* save filename */
			case 's':
			case 'S':
				scanf( "%s", savefilename );
				savefile( savefilename );
				printf( "\ncommand->" );
				break;

			/* exit program */
			case 'e':
			case 'E':
				//quit = 1;
				break;
		} 
	}
}

/*에러처리*/
void usageError( char *message )
{
	fputs( message, stderr );
	fputc( '\n', stderr );
	exit ( 1 );
}

/* 파일 내용 스캔해서 버퍼에 저장  */
void pass1()
{

	int /*tmpfd,*/ charsRead/*, charsWritten*/;
	fd = open( fileName, O_RDWR );//O_RDWR => 단지 읽기 기능
	lineStart[0] = 0; 

//	while (1) 
//	{
		charsRead = read( fd, readBuffer, BUFFER_SIZE );
		if( charsRead == 0 )
			usageError( "read error" );
			//break;
		
		trackLines( readBuffer, charsRead );
//	}
} 

/* 라인 처리 함수 */
void trackLines( char* buffer, int charsRead ) \
{

	int i;
	
	for ( i = 0; i < charsRead; i++ ) 
	{
		++fileOffset;
		if ( buffer[i] == '\n' ) 
			lineStart[++lineCount] = fileOffset;
	}
} 

/* 한 라인 읽어서 화면에 프린트하는 함수 */
void processLine( int i ) 
{ 

	int  charsRead;
	char buffer[BUFFER_SIZE]; 

	lseek( fd, lineStart[i], SEEK_SET ); 
	charsRead = read( fd, buffer, lineStart[i + 1] - lineStart[i] );
	write( 1, buffer, charsRead );
} 

/* lines 변수 분석*/
int checkline( char *lines )
{
	if( strcmp( lines, "*" ) == 0 )			/* all lines */
		return 0;
	
	else if( strchr( lines, '-' ) )			/* a range of lines*/ 
		return 1;
	
	else if( strchr( lines, ',' ) )			/* a list of lines */
		return 2;
	
	else									/* a single line */
		return 3;
}

/* 라인 하나 삭제 */
void Delete ( int num ) 
{ 
	int charsRead;
	//char buffer[BUFFER_SIZE]; 

	lseek( fd, lineStart[num + 1], SEEK_SET );
	charsRead = read( fd, readBuffer, BUFFER_SIZE - lineStart[num + 1] );
	lseek( fd, lineStart[num], SEEK_SET );
	write( fd, readBuffer, charsRead ); 

	lseek( fd, 0L, SEEK_SET );
	charsRead = read( fd, readBuffer, charsRead + lineStart[num] - 1 );
	write( fd, deletedbuffer, charsRead ); 
	write( fd, "\n", 2 );
	lseek( fd, 0L, SEEK_SET );
} 

 /* 여러 라인 샂제 */
void deleteRange( int start, int end ) 
{
	int  charsRead;
	//char buffer[BUFFER_SIZE]; 

	lseek( fd, lineStart[end + 1], SEEK_SET );
	charsRead = read( fd, readBuffer, BUFFER_SIZE - lineStart[end + 1] ); 

	lseek( fd, lineStart[start], SEEK_SET );
	write( fd, readBuffer, charsRead ); 

	lseek( fd, 0L, SEEK_SET );
	charsRead = read( fd, readBuffer, charsRead + lineStart[start] - 1 );
	write(fd, deletedbuffer, charsRead);
	write( fd, "\n", 2 );
}

/* 입력받은 스트링 첨부 */
void insert( int i, char str[] ) 
{
	int  /*temp,*/ charsRead;
	char buffer[BUFFER_SIZE]; 

	lseek( fd, lineStart[i - 1], 0 );
	charsRead = read( fd, buffer, BUFFER_SIZE - lineStart[i] ); 

	lseek( fd, -charsRead, 1 ); 
	write( fd, str, strlen( str ) );
	write( fd, "\n", 2 );
	write( fd, buffer, charsRead );
} 

/* 파일 저장 */
void savefile( char fname[] ) 
{
	int charsRead;
	pass1();
	
	fd = open( fname, O_CREAT|O_RDWR, 0600 );
	charsRead = read( fd, readBuffer, BUFFER_SIZE );
	write( fd, readBuffer, BUFFER_SIZE );
} 
bugiii의 이미지

레....레..... 포트....

에디팅 하는 파일을 직접 억세스 해야 합니까? 메모리에 올려 놓고 하면 안되나요?

kuma의 이미지

Copy 는 시작 Line 과 End Line 을 알아 놓으세요.

Paste 시는 시작 Line 부터 End Line 까지의 Data 를 줄단위로 추가합니다.

단점 : 만일 걸어놓은 위치 중간에 Paste 시 요상한 문제가 -_-;;

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.