我目前正在使用C创建一个缓冲程序所需的项目。在大多数情况下,我的程序已经完成,但我只缺少一个必需的函数:一个位置函数,用于返回头部(数组的开头)到short loc_offset
指定的所需位置之间的距离。
鉴于我已经拥有的东西,我如何从我的短片中返回指向索引或位置的指针?
这是我给出和创建的代码:
主要(plat_bt.c
):
/* File name: platy_bt.c
* Purpose:This is the main program for Assignment #1, CST8152
* Version: 1.18.1
* Author: Svillen Ranev
* Date: 16 January 2018
*/
/* The #define _CRT_SECURE_NO_WARNINGS should be used in MS Visual Studio projects
* to suppress the warnings about using "unsafe" functions like fopen()
* and standard sting library functions defined in string.h.
* The define directive does not have any effect on other compiler projects (gcc, Borland).
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#include "buffer.h"
/* constant definitions */
#define INIT_CAPACITY 200 /* initial buffer capacity */
#define INC_FACTOR 15 /* increment factor */
/*check for ANSI C compliancy */
#define ANSI_C 0
#if defined(__STDC__)
#undef ANSI_C
#define ANSI_C 1
#endif
/* Declaration of an error printing function with
* variable number of arguments
*/
void err_printf(char *fmt, ...);
/* Declaration of a buffer contents display function */
void display (Buffer *ptr_Buffer);
long get_filesize(char *fname);
int main(int argc, char **argv){
pBuffer ptr_Buffer; /* pointer to Buffer structure */
FILE *fi; /* input file handle */
int loadsize = 0; /*the size of the file loaded in the buffer */
int ansi_c = !ANSI_C; /* ANSI C compliancy flag */
/* Check if the compiler option is set to compile ANSI C */
/* __DATE__, __TIME__, __LINE__, __FILE__, __STDC__ are predefined preprocessor macros*/
if(ansi_c){
err_printf("Date: %s Time: %s",__DATE__, __TIME__);
err_printf("ERROR: Compiler is not ANSI C compliant!\n");
exit(1);
}
/* missing file name or/and mode parameter */
if (argc <= 2){
err_printf("\nDate: %s Time: %s",__DATE__, __TIME__);
err_printf("\nRuntime error at line %d in file %s\n", __LINE__, __FILE__);
err_printf("%s\b\b\b\b%s%s",argv[0],": ","Missing parameters.");
err_printf("Usage: platybt source_file_name mode");
exit(1);
}
/* create a source code input buffer */
switch(*argv[2]){
case 'f': case 'a': case 'm': break;
default:
err_printf("%s%s%s",argv[0],": ","Wrong mode parameter.");
exit(1);
}
/*create the input buffer */
ptr_Buffer = b_allocate(INIT_CAPACITY,INC_FACTOR,*argv[2]);
if (ptr_Buffer == NULL){
err_printf("%s%s%s",argv[0],": ","Cannot allocate buffer.");
exit(1);
}
/* open the source file */
if ((fi = fopen(argv[1],"r")) == NULL){
err_printf("%s%s%s%s",argv[0],": ", "Cannot open file: ",argv[1]);
exit (1);
}
/* load a source file into the input buffer */
printf("Reading file %s ....Please wait\n",argv[1]);
loadsize = b_load (fi,ptr_Buffer);
if(loadsize == RT_FAIL1)
err_printf("%s%s%s",argv[0],": ","Error in loading buffer.");
/* close the source file */
fclose(fi);
/*find the size of the file */
if (loadsize == LOAD_FAIL){
printf("The input file %s %s\n", argv[1],"is not completely loaded.");
printf("Input file size: %ld\n", get_filesize(argv[1]));
}
/* display the contents of the input buffer */
display(ptr_Buffer);
/* compact the buffer
* add end-of-file character (EOF) to the buffer
* display again
*/
if(!b_compact(ptr_Buffer,EOF)){
err_printf("%s%s%s",argv[0],": ","Error in compacting buffer.");
}
display(ptr_Buffer);
/* free the dynamic memory used by the buffer */
b_free(ptr_Buffer);
/* make the buffer invalid
It is not necessary here because the function terminates anyway,
but will prevent run-time errors and crashes in future expansions
*/
ptr_Buffer = NULL;
/*return success */
return (0);
}
/* error printing function with variable number of arguments*/
void err_printf( char *fmt, ... ){
/*Initialize variable list */
va_list ap;
va_start(ap, fmt);
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
/* Move to new line */
if( strchr(fmt,'\n') == NULL )
fprintf(stderr,"\n");
}
void display (Buffer *ptr_Buffer){
printf("\nPrinting buffer parameters:\n\n");
printf("The capacity of the buffer is: %d\n",b_capacity(ptr_Buffer));
printf("The current size of the buffer is: %d\n",b_limit(ptr_Buffer));
printf("The operational mode of the buffer is: %d\n",b_mode(ptr_Buffer));
printf("The increment factor of the buffer is: %lu\n",b_incfactor(ptr_Buffer));
printf("The current mark of the buffer is: %d\n", b_mark(ptr_Buffer, b_limit(ptr_Buffer)));
/*printf("The reallocation flag is: %d\n",b_rflag(ptr_Buffer));*/
printf("\nPrinting buffer contents:\n\n");
b_rewind(ptr_Buffer);
b_print(ptr_Buffer);
}
long get_filesize(char *fname){
FILE *input;
long flength;
input = fopen(fname, "r");
if(input == NULL){
err_printf("%s%s","Cannot open file: ",fname);
return 0;
}
fseek(input, 0L, SEEK_END);
flength = ftell(input);
fclose(input);
return flength;
}
该主文件没有错误或警告,它被授予我用作我的主要文件。
这是我编辑的源文件(buffer.c
):
/* File name: buffer.c
* Purpose: This is the main program for Assignment #01, CST8152
* Version: 1.0.3
* Author: Jack Loveday
* Date: 7 Febuary, 2018
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <limits.h>
#include "buffer.h"
/* b_allocate: Creates new buffer on heap
Tries to allocate memory for:
- one Buffer (calloc)
- one dynamic character buffer (char array) (malloc)
Sets buffer operational mode and inc factor
Copies given init_capacity into Buffer capacity val */
Buffer * b_allocate(short init_capacity, char inc_factor, char o_mode) {
Buffer *pBuffer;
if (init_capacity < 0 || (unsigned char)inc_factor < 0)
return NULL;
pBuffer = (Buffer *)calloc(1, sizeof(Buffer));
if (!pBuffer) {
free(pBuffer);
return NULL;
}
pBuffer->cb_head = (char *)malloc(init_capacity);
if (o_mode == 'f' || (unsigned char)inc_factor == 0) {
pBuffer->mode = 0;
pBuffer->inc_factor = 0;
}
else if (o_mode == 'a') {
pBuffer->mode = ADD_MODE;
pBuffer->inc_factor = (unsigned char)inc_factor;
}
else if (o_mode == 'm' && (unsigned char)inc_factor <= 100) {
pBuffer->mode = MULTI_MODE;
pBuffer->inc_factor = (unsigned char)inc_factor;
}
else {
free(pBuffer->cb_head);
free(pBuffer);
return NULL;
}
pBuffer->capacity = init_capacity;
return pBuffer;
}
/* b_addc: resets r_flag to 0 & tries to add symbol to char array pointed by pBD */
pBuffer b_addc(pBuffer const pBD, char symbol) {
char *tBuffer;
short aSpace = 0, newInc = 0, newCapacity = 0;
if (!pBD)
return NULL;
pBD->r_flag = 0;
if ((short)(pBD->addc_offset * sizeof(char)) < pBD->capacity) {
pBD->cb_head[pBD->addc_offset] = symbol;
pBD->addc_offset++;
}
else if ((short)(pBD->addc_offset * sizeof(char)) == pBD->capacity) {
if (pBD->mode == 0)
return NULL;
else if (pBD->mode == 1) {
newCapacity = pBD->capacity + (unsigned char)pBD->inc_factor * sizeof(char);
if (newCapacity <= 0)
return NULL;
pBD->capacity = newCapacity;
}
else if (pBD->mode == -1) {
if (pBD->capacity == SHRT_MAX)
return NULL;
else {
aSpace = SHRT_MAX - pBD->capacity;
newInc = (short)((aSpace * pBD->inc_factor) / 100);
if (!newInc)
newInc = NEW_ONE;
newCapacity = (short)((pBD->capacity + newInc));
if (newCapacity <= 0)
newCapacity = SHRT_MAX;
}
}
tBuffer = (char *)realloc(pBD->cb_head, newCapacity);
if (tBuffer != pBD->cb_head)
pBD->r_flag = SET_R_FLAG;
pBD->cb_head = tBuffer;
pBD->cb_head[pBD->addc_offset] = symbol;
pBD->addc_offset++;
pBD->capacity = newCapacity;
}
return pBD;
}
/* b_clear: retains memory space currently allocated to buffer, but
re-initializes all appropriate members of given Buffer */
int b_clear(Buffer * const pBD){
if (!pBD)
return RT_FAIL1;
pBD->capacity = 0;
pBD->addc_offset = 0;
pBD->getc_offset = 0;
pBD->eob = 0;
return 1;
}
/* b_free: de-allocates memory for char array & Buffer struct */
void b_free(Buffer * const pBD) {
if (pBD) {
free(pBD->cb_head);
free(pBD);
}
}
/* b_isfull: returns 1 if buffer is full, otherwise returns 0, if rt error return -1 */
int b_isfull(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
if ((short)(pBD->addc_offset * sizeof(char)) == pBD->capacity)
return 1;
else
return 0;
}
/* b_limit: returns current limit of buffer, return -1 on error */
short b_limit(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
return pBD->addc_offset;
}
/* b_capacity: returns current capacity of buffer, return -1 on error */
short b_capacity(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
return pBD->capacity;
}
/* b_mark: sets markc_offset to mark, must be between 0 and addc_offset, return -1 on error */
short b_mark(pBuffer const pBD, short mark) {
if (!pBD || mark < 0 || mark > pBD->addc_offset)
return RT_FAIL1;
pBD->markc_offset = mark;
return pBD->markc_offset;
}
/* b_mode: returns value of mode, or -1 on error */
int b_mode(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
return pBD->mode;
}
/* b_infactor: returns non-negative value of inc_factor, return 0x100 (256) */
size_t b_incfactor(Buffer * const pBD) {
if (!pBD)
return NEW_FULL;
return (unsigned char)pBD->inc_factor;
}
/* b_load: returns value of mode */
int b_load(FILE * const fi, Buffer * const pBD) {
char c;
int cNum = 0;
if (!fi || !pBD)
return RT_FAIL1;
for (;;) {
c = (char)fgetc(fi);
if (feof(fi))
break;
if (!b_addc(pBD, c))
return LOAD_FAIL;
++cNum;
}
fclose(fi);
return cNum;
}
/* b_isempty: if addc_offset is 0 return 1, otherwise return 0, return -1 on error */
int b_isempty(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
if (!pBD->addc_offset)
return 1;
else
return 0;
}
/* b_eob: returns eob (end of buffer), returns -1 on error */
int b_eob(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
return pBD->eob;
}
/* b_getc: checks logic, if not valid returns -2, if getc_offset and addc_offset
are equal, set eob to 1 and returns -1, otherwise set eob to 0 */
char b_getc(Buffer * const pBD) {
char returner;
if (!pBD || !pBD->cb_head)
return RT_FAIL2;
if (pBD->getc_offset == pBD->addc_offset) {
pBD->eob = 1;
return RT_FAIL1;
}
else {
pBD->eob = 0;
}
returner = *(pBD->cb_head + pBD->getc_offset);
pBD->getc_offset++;
return returner;
}
/* b_print: used for diagnostic purposes only, returns -1 on error */
int b_print(Buffer * const pBD) {
int numOfChars = 0;
char c;
if (!pBD->addc_offset) {
printf("The Buffer is empty.\n");
return numOfChars;
}
pBD->getc_offset = 0;
while (1) {
c = b_getc(pBD);
if (b_eob(pBD))
break;
printf("%c", c);
++numOfChars;
}
numOfChars = pBD->getc_offset;
pBD->getc_offset = 0;
printf("\n");
return numOfChars;
}
/* b_compact: shrinks buffer to new capacity, before returning to a pointer add symbol
to the end of buffer, must set r_flag appropriatley */
Buffer * b_compact(Buffer * const pBD, char symbol) {
char *tempBuffer;
short tempCap;
if (!pBD)
return NULL;
tempCap = (pBD->addc_offset + 1) * sizeof(char);
if (tempCap == SHRT_MAX)
return pBD;
tempBuffer = (char *)realloc(pBD->cb_head, (unsigned short)tempCap);
if (tempCap == 0)
return NULL;
if (tempBuffer != pBD->cb_head)
pBD->r_flag = SET_R_FLAG;
pBD->cb_head = tempBuffer;
pBD->capacity = tempCap;
return pBD;
}
/* b_rflag: returns r_flag, returns -1 on error */
char b_rflag(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
return pBD->r_flag;
}
/* b_retract: decrements getc_offset by 1, returns -1 on error, otherwise returns getc_offset */
short b_retract(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
pBD->getc_offset--;
return pBD->getc_offset;
}
/* b_reset: sets getc_offset to current markc_offset, returns -1 on error and getc_offset otherwise */
short b_reset(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
pBD->getc_offset = pBD->markc_offset;
return pBD->getc_offset;
}
/* b_getcoffset: returns getc_offset, or returns -1 on error */
short b_getcoffset(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
return pBD->getc_offset;
}
/* b_rewind: set getc_offset and markc_offset to 0, return -1 on error and 0 otherwise */
int b_rewind(Buffer * const pBD) {
if (!pBD)
return RT_FAIL1;
pBD->addc_offset = 0;
pBD->markc_offset = 0;
return 0;
}
/* b_location: returns a pointer to location indicated by loc_offset, returns null on error */
char * b_location(Buffer * const pBD, short loc_offset) {
if (!pBD)
return NULL;
return *loc_offset;
}
最后我的buffer.h
:
/*File Name: buffer.h
* Version: 1.18.1
* Author: S^R
* Date: 16 January 2018
* Preprocessor directives, type declarations and prototypes necessary for buffer implementation
* as required for CST8152-Assignment #1.
* The file is not completed.
* You must add your function declarations (prototypes).
* You must also add your constant definitions and macros,if any.
*/
#ifndef BUFFER_H_
#define BUFFER_H_
/*#pragma warning(1:4001) *//*to enforce C89 type comments - to make //comments an warning */
/* standard header files */
#include <stdio.h> /* standard input/output */
#include <malloc.h> /* for dynamic memory allocation*/
#include <limits.h> /* implementation-defined data type ranges and limits */
/* constant definitions */
/* You may add your own constant definitions here */
#define RT_FAIL1 -1 /* fail return value */
#define RT_FAIL2 -2 /* fail return value */
#define LOAD_FAIL -2 /* load fail error */
#define SET_R_FLAG 1 /* realloc flag set value */
#define ADD_MODE 1; /* named constant for additive mode */
#define MULTI_MODE -1; /* named constant for multiplicative mode */
#define NEW_ONE 1; /* generic named constant value of 1 */
#define NEW_FULL 256; /* generic named constant value of 256 */
/* user data type declarations */
typedef struct BufferDescriptor {
char *cb_head; /* pointer to the beginning of character array (character buffer) */
short capacity; /* current dynamic memory size (in bytes) allocated to character buffer */
short addc_offset; /* the offset (in chars) to the add-character location */
short getc_offset; /* the offset (in chars) to the get-character location */
short markc_offset; /* the offset (in chars) to the mark location */
char inc_factor; /* character array increment factor */
char r_flag; /* reallocation flag */
char mode; /* operational mode indicator*/
int eob; /* end-of-buffer flag */
} Buffer, *pBuffer;
/* function declarations */
/*
Place your function declarations here.
Do not include the function header comments here.
Place them in the buffer.c file
*/
Buffer * b_allocate(short init_capacity, char inc_factor, char o_mode);
pBuffer b_addc(pBuffer const pBD, char symbol);
int b_clear(Buffer * const pBD);
void b_free(Buffer * const pBD);
int b_isfull(Buffer * const pBD);
short b_limit(Buffer * const pBD);
short b_capacity(Buffer * const pBD);
short b_mark(pBuffer const pBD, short mark);
int b_mode(Buffer * const pBD);
size_t b_incfactor(Buffer * const pBD);
int b_load(FILE * const fi, Buffer * const pBD);
int b_isempty(Buffer * const pBD);
int b_eob(Buffer * const pBD);
char b_getc(Buffer * const pBD);
int b_print(Buffer * const pBD);
Buffer * b_compact(Buffer * const pBD, char symbol);
char b_rflag(Buffer * const pBD);
short b_retract(Buffer * const pBD);
short b_reset(Buffer * const pBD);
short b_getcoffset(Buffer * const pBD);
int b_rewind(Buffer * const pBD);
char * b_location(Buffer * const pBD, short loc_offset);
#endif
所以,我需要在b_location函数中找到loc_offset的位置并将其作为指针返回。提前谢谢!
答案 0 :(得分:1)
custom action