⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tedit.c

📁 Software Development in C: A Practical Approach to Programming and Design 软件开发:编程与设计(C))——国外经典教材·计
💻 C
字号:
//---------------------------------------------------------
/*
File Name:	TEdit.c
Comments:	This file contains the functions which 
			implement the text editor.
*/
//---------------------------------------------------------




//---------------------------------------------------------
// Include files

#include <stdio.h>
#include <stdlib.h>
#include "MiscType.h"
#include "TBuffer.h"

// End Include files
//---------------------------------------------------------



//---------------------------------------------------------
// Constants

const int SCREEN_HEIGHT = 25;
const int TEXT_AREA_HEIGHT = 18;

#define SCROLL_LINE_UP_COMMAND		'U'
#define SCROLL_LINE_DOWN_COMMAND	'D'
#define SCROLL_PAGE_UP_COMMAND		'B'
#define SCROLL_PAGE_DOWN_COMMAND	'F'
#define EDIT_TEXT_COMMAND			'E'
#define QUIT_COMMAND				'Q'
#define SAVE_COMMAND				'S'
#define LOAD_COMMAND				'L'

#define BLANK_INPUT_STRING								\
			"                                        "

#define MAX_LINE_NUMBER_DIGITS 5

// End Constants
//---------------------------------------------------------




//---------------------------------------------------------
// Types

typedef enum
{
	EDE_NO_ERROR,
	EDE_MEMORY_ALLOCATION_ERROR,
	EDE_CANT_SAVE_FILE,
	EDE_CANT_LOAD_FILE
} editor_error;

// end Types
//---------------------------------------------------------




//---------------------------------------------------------
// Prototypes

void ClearScreen(void);
void DisplayText(const text_buffer * const tBuffer);
void PrintMenu(void);
char GetUserCommand(void);
editor_error EditBuffer(text_buffer *textBuffer);
editor_error SaveBuffer(text_buffer *theBuffer);
editor_error LoadBuffer(text_buffer *theBuffer);

// End Prototypes
//---------------------------------------------------------




int main()
{
	char userCommand = ' ';
	boolean done;
	text_buffer textBuffer;
	int errorStatus=0;

	// Initialize the text buffer.
	TextBufferInitialize(&textBuffer);

	// While the user does not want to quit...
	for (done=FALSE;(!done) && (!errorStatus);)
	{
		// Clear the screen.
		ClearScreen();

		// Display a page of text.
		DisplayText(&textBuffer);

		// Display the menu.
		PrintMenu();

		// Get the user's command.
		userCommand = GetUserCommand();

		switch (userCommand)
		{
			// If the user wants to scroll up one line...
			case SCROLL_LINE_UP_COMMAND:
				// Scroll the buffer up one line.
				TextBufferScrollUp(1,&textBuffer);
			break;

			// If the user wants to scroll up one screenful...
			case SCROLL_PAGE_UP_COMMAND:
				// Scroll the buffer up one screenful.
				// Leave an overlap of one line.
				TextBufferScrollUp(TEXT_AREA_HEIGHT-1,
								   &textBuffer);
			break;

			// If the user wants to scroll down one line...
			case SCROLL_LINE_DOWN_COMMAND:
				// Scroll the buffer down one line.
				TextBufferScrollDown(1,TEXT_AREA_HEIGHT,
								     &textBuffer);
			break;

			// If the user wants to scroll down one screenful...
			case SCROLL_PAGE_DOWN_COMMAND:
				// Scroll the buffer down one screenful.
				TextBufferScrollDown(TEXT_AREA_HEIGHT-1,
								     TEXT_AREA_HEIGHT,
									 &textBuffer);
			break;

			// If the user wants to edit text...
			case EDIT_TEXT_COMMAND:
				errorStatus = EditBuffer(&textBuffer);
			break;

			// If the user wants to save the buffer to a file...
			case SAVE_COMMAND:
				if (SaveBuffer(&textBuffer) != EDE_NO_ERROR)
				{
					printf("\nThe program can't save the file.\n");
					printf("Please try using another file name.\n");
					printf("Press Enter to continue...");
					getchar();
					rewind(stdin);
				}
			break;

			// If the user wants to load a file...
			case LOAD_COMMAND:
				if (LoadBuffer(&textBuffer) != EDE_NO_ERROR)
				{
					printf("\nThe program can't load the file.\n");
					printf("Please be sure you typed the file name correctly.");
					printf("\nPress Enter to continue...");
					getchar();
					rewind(stdin);
				}
			break;

			// If the user wants to quit...
			case QUIT_COMMAND:
				// Set the loop control variable to exit.
				done = TRUE;
			break;

			// Else the command is not recognized...
			default:
				// Print an error message.
				printf("Command not recognized.\n");
				printf("Press Enter to continue...");
				getchar();
				rewind(stdin);
			break;
		}
	}

	// If there was an error...
	if (errorStatus)
	{
		// Print an error message.
		printf("Fatal Error: Press Enter to abort program...\n");
		getchar();
	}

	TextBufferFree(&textBuffer);

	return (errorStatus);
}






//---------------------------------------------------------
/* 
Function Name:	ClearScreen
Parameters:
	In:			None.
	Out:		None. 
	In/Out:		None.
Return Values:	None.
Comments:		This function clears the screen by printing
				newlines.
*/

void ClearScreen(void)
{
	int i;

	// For each line on the screen...
	for (i=0;i<SCREEN_HEIGHT;i++)
	{
		// Print a newline.
		printf("\n");		
	}

}

// End ClearScreen
//---------------------------------------------------------




//---------------------------------------------------------
/* 
Function Name:	DisplayText
Parameters:
	In:			tBuffer - A pointer to the text buffer 
					that will be displayed on the screen.
	Out:		None.
	In/Out:		None.
Return Values:	None.
Comments:		This function starts with the current top 
				row in the text buffer and prints 
				successive rows of text from the buffer 
				to the screen. It stops when it reaches 
				the maximum number of rows to be displayed.

				This function prints the display line number 
				before each row of text. The user sees the 
				both the display line number as beginning 
				with 1 rather than 0. This is more 
				intuitive for the user.
*/

void DisplayText(const text_buffer * const tBuffer)
{
	int i,length;
	text_string tempString;
	int topRow;

	TextStringInitString(&tempString);

	topRow = TextBufferGetTopLine(tBuffer);
	length = TextBufferGetBufferLength(tBuffer);

	printf("Line\n");
	printf("Number\n");

	// For each row to be displayed...
	for (i=0;i<TEXT_AREA_HEIGHT;i++)
	{
		// Print the line number.
		printf("  %d",i+1);

		// Print some spaces.
		if (i+1<10)
		{
			printf("     ");
		}
		else
		{
			printf("    ");
		}

		// If the row number is valid...
		if ((length > 0) && (i < length))
		{
			// Get a row of text.
			TextBufferGetRow(topRow+i,&tempString,tBuffer);

			// Print it to the screen.
			TextStringPrintString(&tempString);
		}
		printf("\n");
	}

	TextStringFree(&tempString);
}

// End DisplayText
//---------------------------------------------------------




//---------------------------------------------------------
/* 
Function Name:	PrintMenu
Parameters:
	In:			None.
	Out:		None.
	In/Out:		None.
Return Values:	None.
Comments:		The PrintMenu function prints the menu of
				text editor commands to the screen.
*/


void PrintMenu(void)
{
	// Print the commands recognized by the text editor.
	printf("Press one of the following keys to issue a ");
	printf("command, then press the Enter key.\n");
	printf("%c Scroll up one line.",
		   SCROLL_LINE_UP_COMMAND);
	printf("  %c Scroll down one line.",
		   SCROLL_LINE_DOWN_COMMAND);
	printf("  %c Scroll up one page.",
		   SCROLL_PAGE_UP_COMMAND);
	printf("\n");
	printf("%c Scroll down one page.",
		   SCROLL_PAGE_DOWN_COMMAND);
	printf("  %c Edit text.",EDIT_TEXT_COMMAND);
	printf("  %c Load file.",LOAD_COMMAND);
	printf("  %c Save file.",SAVE_COMMAND);
	printf("  %c Quit.\n",QUIT_COMMAND);
	printf("COMMAND>>>");
}

// End PrintMenu
//---------------------------------------------------------




//---------------------------------------------------------
/* 
Function Name:	GetUserCommand
Parameters:
	In:			None.
	Out:		None.
	In/Out:		None.
Return Values:	This function return a single-character
				user command.
Comments:		The GetUserCommand() function retrieves a 
				character command from the keyboard. The 
				user must type the character, followed by 
				the Enter key. If the Enter key is not 
				pressed, this function waits until it is.

				After the command is retrieved, there is 
				still a newline character left in the
				keyboard buffer. This function will pull 
				it out and throw it away.
*/

char GetUserCommand(void)
{
	char userInput;

	// Get the user's command from the keyboard.
	userInput = getchar();
	userInput = toupper(userInput);	// Convert to upper case

	// Flush the keyboard buffer.
	rewind(stdin);

	// Return the command.
	return (userInput);
}

// End GetUserCommand
//---------------------------------------------------------




//---------------------------------------------------------
/* 
Function Name:	EditBuffer
Parameters:
	In:			None.
	Out:		None.
	In/Out:		textBuffer - Contains a pointer to the 
					buffer to be updated.
Return Values:	This function returns EDE_NO_ERROR if it was 
				successful. Otherwise, it returns 
				EDE_MEMORY_ALLOCATION_ERROR.
Comments:		The EditBuffer function enables the user to
				enter a line of text into the text buffer.

				Note that when the user enters a line number
				to edit, the line number will always be 1-based,
				not 0-based. Therefore, it must be decremented
				before it is used.

*/

editor_error EditBuffer(text_buffer *textBuffer)
{
	int lineNumber=0;
	int topLine;
	char inputString[MAX_LINE_NUMBER_DIGITS];
	int errorStatus;
	boolean gotValidInput = FALSE;
	boolean done = FALSE;
	text_string tempString;

	TextStringInitString(&tempString);

	// Set the string to a line of blanks.
	if (TextStringSetFromCharArray(
			&tempString,
			BLANK_INPUT_STRING) != TSE_NO_ERROR)
	{
		errorStatus = EDE_MEMORY_ALLOCATION_ERROR;
	}

	// If the string was properly set...
	if (!errorStatus)
	{
		topLine = TextBufferGetTopLine(
						textBuffer);

		do
		{
			// Prompt the user for the line to edit.
			printf("Please input the line number of ");
			printf("the row of text to edit\n>>>");

			// Get the user's input.
			gets(inputString);
			lineNumber = atoi(inputString);

			// If the user just pressed Enter...
			if (inputString[0] == '\0')
			{
				// He/She is done.
				done = TRUE;
			}
			// else if the user typed valid input...
			else if ((lineNumber > 0) && 
					(lineNumber <= TEXT_AREA_HEIGHT))
			{
				gotValidInput = TRUE;
			}
			// Else the user entered invalid input...
			else
			{
				printf("\nError: ");
				printf("That is not a valid line number.\n");
				printf("Press Enter to continue. ");
				getchar();
				rewind(stdin);
			}

		} while ((!gotValidInput) && (!done));

		// If the user typed valid input...
		 if (gotValidInput)
		{
			// Prompt the user for a line of text.
			printf("Please type in a line of text\n");
			printf(">>>");

			// Get the user's input.
			TextStringScanString(&tempString);

			lineNumber--;

			// Store the new text in the specified row.
			if (TextBufferSetRow(
					textBuffer->topLine+lineNumber,
					&tempString,
					textBuffer) != TBE_NO_ERROR)
			{
				errorStatus = EDE_MEMORY_ALLOCATION_ERROR;
			}
		}
	}

	// If the temp string was used...
	if (TextStringGetLength(&tempString) > 0)
	{
		// Its memory must be released.
		TextStringFree(&tempString);
	}

	return (errorStatus);
}

// End EditBuffer
//---------------------------------------------------------




//---------------------------------------------------------
/* 
Function Name:	SaveBuffer
Parameters:
	In:			None.
	Out:		None.
	In/Out:		textBuffer - Contains a pointer to the 
					buffer to be saved.
Return Values:	If this function is successful, it returns 
				EDE_NO_ERROR. Otherwise, it returns 
				EDE_CANT_SAVE_FILE.
Comments:		The SaveBuffer function prompts the user for a 
				file name and saves the buffer to that file.

*/

editor_error SaveBuffer(text_buffer *theBuffer)
{
	text_string fileName;
	editor_error errorStatus = EDE_NO_ERROR;

	TextStringInitString(&fileName);

	// Prompt the user for a file name.
	printf("Please enter a file name>>>");
	
	// If the user entered a file name...
	if (TextStringScanString(&fileName) > 0)
	{
		// Attempt to save the buffer.
		if (TextBufferSaveFile(
				theBuffer,
				&fileName) != TBE_NO_ERROR)
		{
			errorStatus = EDE_CANT_SAVE_FILE;
		}
	}
	// Else the user did not enter a file name...
	else
	{
		errorStatus = EDE_CANT_SAVE_FILE;

		// Print an error message.
		printf("No file name was entered.\n");
		printf("Press Enter to continue...");
		getchar();
		rewind(stdin);
	}

	TextStringFree(&fileName);

	return (errorStatus);
}

// end SaveBuffer
//---------------------------------------------------------




//---------------------------------------------------------
/* 
Function Name:	LoadBuffer
Parameters:
	In:			None.
	Out:		None.
	In/Out:		textBuffer - Contains a pointer to the 
					buffer into which the file will be 
					loaded.
Return Values:	If this function is successful, it returns 
				EDE_NO_ERROR. Otherwise, it returns 
				EDE_CANT_LOAD_FILE.
Comments:		The LoadBuffer() function prompts the user for a 
				file name and loads the buffer with characters
				from that file.

*/

editor_error LoadBuffer(text_buffer *theBuffer)
{
	text_string fileName;
	editor_error errorStatus = EDE_NO_ERROR;

	TextStringInitString(&fileName);

	// Prompt the user for a file name.
	printf("Please enter a file name>>>");
	// If the user entered a file name...
	if (TextStringScanString(&fileName) > 0)
	{
		// Attempt to load the buffer.
		if (TextBufferLoadFile(
				theBuffer,
				&fileName) != TBE_NO_ERROR)
		{
			errorStatus = EDE_CANT_LOAD_FILE;
		}
	}
	// Else the user did not enter a file name...
	else
	{
		errorStatus = EDE_CANT_LOAD_FILE;

		// Print an error message.
		printf("No file name was entered.\n");
		printf("Press Enter to continue...");
		getchar();
		rewind(stdin);
	}

	TextStringFree(&fileName);

	return (errorStatus);
}

// end LoadBuffer
//---------------------------------------------------------



// End TEdit.c
//---------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -