函数溢出错误 [英] Overflow error in function

查看:131
本文介绍了函数溢出错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C编程新手,我一直在编写一个虚拟计算机程序,它接受来自STDIN的输入,输入基本上代表虚拟计算机执行多个特定数字检查的命令 - 只是简单的东西。本质上,当我第一次写这个程序时,我正在使用指向文件流的文件指针从文件中读取我的输入,但是当我将流切换到STDIN时,它开始变得很奇怪。



这个STDIN有趣的地方在于它是一个文件流重定向,所以我仍然在命令行参数中提供一个文件,但是因为我使用了一个编码平台,它有一个允许文件重定向的命令,而不必实现一个实际的文件指针它让我感到困惑。

我开始出现溢出错误,这些错误在我使用命令行参数中提供的程序的文件指针时并未发生,我不知道为什么我刚刚将我的文件指针流切换到标准输入,。我非常感谢,如果有人能指出我的问题可能是什么,这里是我得到溢出错误的代码:

  #include< stdio.h> 
#include< stdlib.h>
#include< string.h>
$ b $ / *调用原型注:我不会调用execute / compile,因为它们在主方法之前* /

int printMemory(int * accumulator,int * instructionCounter ,int * instructionRegister,int * operationCode,int * operand,int memory []);
int checkSegmentationFault(int * operand);
int checkWordFlow(int instructionCounter,int memory []);
$ b / *
函数名称:compile
参数:指向我们正在处理的文件的指针,存储器数组,指向instructionCounter,instructionRegister,operationCode和操作数的指针,以便我们可以对它们进行操作
返回值:如果成功编译则返回1,否则返回0或终止。
合作伙伴:无
说明:该函数通过它的指针逐行读入文件,然后将其数据转换为4位数值,然后将它们存储到存储器阵列中。收益函数检查一些编译错误,然后返回结果。
* /

int compile(FILE * fPointer,int memory [],int * instructionCounter,int * instructionRegister,int * operationCode,int * operand){
char s [ 80]; / *缓冲区* /
* instructionRegister = 0;
* operationCode = 0; (((* instructionRegister)= fscanf(fPointer,%d%s%d,operationCode,s,operand))!!= EOF){/ *一行一行地读取数据,然后存储返回的整数((* instructionRegister)== 3){/ *通过将当前指令寄存器的计数与3进行比较来检查格式不正确,否则返回不正确的格式* / $ (*操作数> 9999 || *操作数< 0){/ *检查编译器中的字溢出,确保数字不超过9999 * /
printf(尝试放置一个字在大于4位数的内存中,或试图以负值传递......);
exit(0);
}
/ *比较代码的字符串部分,并检查它是否与下列单词相匹配,然后通过在其中添加操作数* /
将其转换为4位数值if( strcmp(s,READ)== 0){
memory [* operationCode] = 10 * 100 + * operand;
}
else if(strcmp(s,WRIT)== 0){
memory [* operationCode] = 11 * 100 + * operand;
}
else if(strcmp(s,LOAD)== 0){
memory [* operationCode] = 20 * 100 + * operand;
}
else if(strcmp(s,PRNT)== 0){
memory [* operationCode] = 12 * 100 + * operand;
}
else if(strcmp(s,STOR)== 0){
memory [* operationCode] = 21 * 100 + * operand;
}
else if(strcmp(s,SET)== 0){
memory [* operationCode] = * operand;
}
else if(strcmp(s,ADD)== 0){
memory [* operationCode] = 30 * 100 + * operand;
}
else if(strcmp(s,SUB)== 0){
memory [* operationCode] = 31 * 100 + * operand;
}
else if(strcmp(s,DIV)== 0){
memory [* operationCode] = 32 * 100 + * operand;
}
else if(strcmp(s,MULT)== 0){
memory [* operationCode] = 33 * 100 + * operand;
}
else if(strcmp(s,MOD)== 0){
memory [* operationCode] = 34 * 100 + * operand;
}
else if(strcmp(s,BRAN)== 0){
memory [* operationCode] = 40 * 100 + * operand;
}
else if(strcmp(s,BRNG)== 0){
memory [* operationCode] = 41 * 100 + * operand;
}
else if(strcmp(s,BRZR)== 0){
memory [* operationCode] = 42 * 100 + * operand ;;
}
else if(strcmp(s,HALT)== 0){
memory [* operationCode] = 9999;


else {/ *打印回给用户,编译器无法识别其中的一个命令,因为它正在经历它* /
printf(这是一个未知命令,命令区分大小写,程序将立即退出\\\
);
exit(0);


$ b else {/ *如果instructionRegister不匹配,则返回不正确的格式3 * /
printf(格式不正确,程序现在退出\\\
);
exit(0);



$ b / *检查指令数据是否包含HALT,如果不是,它将终止* /
while(* instructionCounter <100 ){
if(memory [* instructionCounter] == 9999){
return 1;
}
else
(* instructionCounter)++;
}
printf(找不到暂停,程序现在退出);
exit(0);


$ b函数名称:execute
参数:accumulator用于存储在数学运算中,instructionCounter用于计算指令,instructionRegister用于存储当前指令,
操作码存储前两位数字,以便它能识别当前正在执行的命令,操作数存储下两位数字,并且存储器能够循环通过计算机100内存
返回值(s) :如果执行正常则返回1,否则如果发现错误则会终止。它还会打印出一旦发现显示内存当前状态的HALT。
合作伙伴:无
说明:该函数处理编译后的指令,并根据它们的操作代码开始对它们执行操作,它还检查错误,然后在达到HALT时打印出当前内存状态,
* /

int execute(int * accumulator,int * instructionCounter,int * instructionRegister,int * operationCode,int * operand,int memory [])
{
/ *将值重置为零,因为它们在编译器中使用* /
* operand = 0;
* operationCode = 0;
* instructionRegister = 0;
* instructionCounter = 0;
* accumulator = 0;
$ b $ *此循环开始查看4位数的存储单元,并在(* instructionCounter< 100){

checkWordFlow( * instructionCounter,memory);

* instructionRegister = memory [* operand]; / *存储当前指令* /

*操作数=内存[* instructionCounter]%100; / *存储2位数字* /

checkSegmentationFault(操作数); / *检查操作数不包含负值,以便问题不会抛出seg错误* /

* operationCode = memory [* instructionCounter] / 100; / *存储2个左边的diigts * /

if(* operationCode == 10){/ * READ:询问用户提供输入并将其存储在指令中的指定地址* /

scanf(%d,& memory [* operand]);

$ b else if(* operationCode == 11){/ * WRIT *:执行时打印出内存元素中的数据* /
printf(%d \\ \
,存储器[*操作数]);


else if(* operationCode == 12){/ * PRNT * /

while(1){/ *循环并打印下列值((memory [* operand] / 100> 65&& amp;& amp; amp; lt;存储器[*操作数] / 100 <90)||存储器[*操作数] / 100 == 10)
printf(%c,存储器[*操作数] / 100)
else if(memory [* operand] / 100 == 0){
break;
}
else {
printf(Unknown Character \\\
);
exit(0); ((存储器[*操作数]%100> 65&存储器[*操作数]%100< 90)||存储器[*操作数]%100 == 10)


printf(%c,内存[*操作数]%100);
else if(memory [* operand]%100 == 0){
break;
}

else {
printf(Unknown Character \\\
);
exit(0);
}

(* operand)++;
}
* operand = 0; / *重新设置操作数的值,因为它是增加的,所以它不会弄乱HALT打印* /
printf(\\\
);

else if(* operationCode == 20){/ * LOAD:加载到累加器* /
* accumulator = memory [* operand]; $ *

$ b else if(* operationCode == 21){/ * STORE:将累加器值存储到特定的存储单元中* /
memory [* operand] = * accumulator ;
}

else if(* operationCode == 30){/ * ADD:在累加器中添加特定的内存地址数据* /
* accumulator + = memory [* operand] ;
}

else if(* operationCode == 31){/ * SUB:从累加器中减去指定的memoery地址数据* /
* accumulator = * accumulator - memory [ *操作数];

else if(* operationCode == 32){/ * DIV:从累加器中分出特定的内存地址数据* /

if(memory [* operand]> ; 0){/ *句柄除零错误* /
* accumulator = *累加器/内存[*操作数];
}
else {
printf(零分区被尝试\\\
程序现在退出\\\
);
exit(0);

$ b $ else if(* operationCode == 33){/ * MULT:将指定的地址数据乘以累加器* /
* accumulator = * accumulator * memory [ *操作数]; $ * b
$ else if(* operationCode == 34){/ * MOD:计算指定地址数据的累加器的余数* /
*累加器= *累加器%内存[*操作数] ;

else if(* operationCode == 40){/ * BRAN:跳转内存执行以解决给定* /
* instructionCounter = *操作数;
(* instructionCounter) - ; / *将计数器减1,以便循环不跳过指令* /
}
else if(* operationCode == 41){/ * BRNG:只有在累加器为如果(*累加器<0){
* instructionCounter = *操作数;否则* /


(* instructionCounter) - ; / *将计数器减1以便循环不跳过指令* /

}
}
else if(* operationCode == 42){/ * BRZR jump memory只有在累加器为零时才执行到内存位置* /

if(* accumulator == 0){
* instructionCounter = * operand;
(* instructionCounter) - ; / *将计数器减1以便循环不跳过指令* /
}
}
else if(* operationCode == 99){/ * HALT:终止程序但打印在执行该操作之前退出内存状态* /
printMemory(accumulator,instructionCounter,instructionRegister,operationCode,operand,memory); / *打印出内存* /
exit(0);

else if(* operationCode == 0){/ *检查空元素并移动它们* /
(* instructionCounter)++;
继续;
}

else {/ *处理无法识别的操作码* /
printf(未知命令,程序现在退出\ n);
exit(0);
}

(* instructionCounter)++; / *将循环加1并开始下一轮循环* /

}
return 1;
}
int main(int argc,char * argv []){
FILE * fPointer = NULL;
char fileName [150];
int accumulator = 0;
signed int instructionCounter = 0;
signed int instructionRegister = 0;
int operationCode = 0;
int operand = 0;
signed int memory [100];
检查用户是否在命令行传入参数* /
if(argc <1){
puts(您没有指定参数或参数N);
exit(0); (argc> 1)
strcpy(fileName,argv [1]);如果(argc> 1)
/ *填充缓冲区* /
;


fPointer = stdin;
/ *如果文件无法打开,则会抛出一个错误* /
if(fPointer == NULL){
puts(File failed to open \\\
);
exit(0);


/ *这个循环用零填充* /
((instructionCounter = 0; instructionCounter< 100; instructionCounter ++){
memory [instructionCounter] = 0;
}
instructionCounter = 0;


/ *运行命令* /

compile(fPointer,memory,& instructionCounter,& instructionRegister,& operationCode,& operand);
执行(& accumulator,& instructionCounter,& instructionRegister,& operationCode,& operand,memory);
返回1;

$ b $ * b $ b函数名称:printMemory
参数:累加器,指令计数器,指令寄存器,操作码,操作数,存储器阵列,以确保打印出正确的内存状态,我们必须将它们传递给
返回值:返回1,但打印出内存状态之前,它会执行
合作伙伴:无
说明:打印当前状态内存格式很好的格式
* /

int printMemory(int * accumulator,int * instructionCounter,int * instructionRegister,int * operationCode,int * operand,int memory []) {
printf(REGISTERS:\\\
accumulator%+ 05d\\\
instructionCounter%02d\\\
instructionRegister%+ 05d\\\
operationCode%02d\\\
operand%02d\\\

* accumulator,* instructionCounter,* instructionRegister,* operationCode,* operand);
* instructionCounter = 0;

printf(MEMORY:\\\
0 1 2 3 4 5 6 7 8 9 \\\
); (*指令计数器)= 0;(*指令计数器)<100;(*指令计数器)+ = 10)/ *循环遍历存储器阵列并输出每行10个元素* /
{
printf(%2d,* instructionCounter);
printf(%+ 05d%+ 05d%+ 05d%+ 05d%+ 05d%+ 05d%+ 05d%+ 05d%+ 05d%+ 05d \ n,内存[*指令计数器],内存[ * instructionCounter + 1],memory [* instructionCounter + 2],memory [* instructionCounter + 3],memory [* instructionCounter + 4],
memory [* instructionCounter + 5],memory [* instructionCounter + 6],内存[*指令计数器+ 7],内存[*指令计数器+ 8],内存[*指令计数器+ 9]);

}
返回1;
}
/ *
函数名称:checksegmentationFault
参数:操作数。
返回值:返回0,如果程序试图访问未知操作数,可能为负值,则终止程序。
合作伙伴:无
描述:如果程序尝试访问一个未知的操作数,可能为负值,则终止程序。
* /

int checkSegmentationFault(int * (*操作数< 0 || *操作数> 100){
printf(分段故障:尝试访问未知地址\ n);
{
if;
exit(0);
}
返回0;


函数名:checkWordFlow
参数:用于循环的指令计数器和存储器数组
返回值:1,如果到达一个字则终止溢出
合作伙伴:无
说明:此函数通过检查数字值不超过9999,
* /

int checkWordFlow(int instructionCounter,int memory [])/ *修正这个狗屎* /
{
instructionCounter = 0;
while(instructionCounter <100){
if(memory [instructionCounter]> 9999)
{printf(Word在内存元素溢出%d \程序将退出\ n ,instructionCounter);
exit(0);
}
instructionCounter ++;
}
返回1;





$ b

输入流看起来像这样:(就像我上面提到的这个流正在被VIM命令重定向,它欺骗程序从文件中读取,而不必实际实现文件指针)

  01 READ 60 
02 LOAD 60
SUB SUB 61
04 STOR 60
05 BRNG 15
06 READ 70
07 LOAD 70
08 ADD 80
09 STOR 80
10 LOAD 60
11 SUB 61
12 STOR 60
13 BRNG 15
14 BRAN 6
15 WRIT 80
16 HALT 99
61 SET 1
80 SET 0

I几个小时我一直在挠头,我不知道为什么它会这样做,正如我所说我是C编程的新手,但我仍然不知道如何调试和执行C语言,我来自Java背景。编辑1:用户不会将程序写入虚拟计算机,程序已经写入,并且用户只需通过VIM中的命令重定向到STDIN就可以了,如下所示: <.c $ c>(./ computer< prog1)(./ computer< prog2)。程序应该编译成功,然后当计算机确定它是什么类型的程序时,它将根据它的任务提示用户输入。因此,它可以要求用户输入值,然后计算它们的平均值,如果那是重定向到的程序。 解决方案

p>如果您正在接受用户的输入,那么代码会有所不同。



有几个选项,


  1. 保留相同的代码,但在输入所有数据后,在用户的条件下按 Ctrl-Z 。这只有在你是唯一一个输入数据的人时才有效,并且通常不可行。

  2. 在每个循环之后,你可以询问用户他是否想要输入更多数据。然后,如果用户输入 y ,则可以将输入作为 y / n 进行循环。

下面是一个例子。

  do 
{
scanf(%d%79s%d,operationCode,s,operand));
//其他代码

printf(\\\
你想输入另一个值(y / n));
scanf(%c,& check);
} while(check!='n);




  1. 循环使用固定的次数,但您的原始代码无法如此工作,这对您而言不是一个好选择。


I'm new to C programming and I've been writing a virtual computer program that takes input from STDIN , the inputs basically represents commands that task the Virtual computer to perform a multiple of a certain number check - just simple stuff. Essentially when I first wrote this program I was reading my input from a file using file pointers that direct to file streams , but then when I switched my stream to STDIN it started getting weird.

The interesting thing about this STDIN is that it's a file stream redirection, so I am still providing a file in command line argument , but since I use a coding platform that has a command that allows file redirection without having to implement an actual file pointer it's getting me confused.

I started getting overflow errors that did not occur when I used to have file pointers to the programs that are being provided in the command line argument, I have no idea why as I have just switched my file pointer stream to stdin`, . I would greatly appreciate it if someone could point out to me what the problem could likely be, here is the code that I'm getting the overflow errors from:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*Calling in the prototypes NOTE: I don't call execute/compile because they preceed the main method */

int printMemory(int* accumulator, int* instructionCounter, int* instructionRegister,int*operationCode,int* operand, int memory []);
int checkSegmentationFault(int *operand);
int checkWordFlow(int instructionCounter, int memory []);

/* 
Function Name: compile
Parameters: A pointer to the file that we are processing, the memory array, a pointer to  instructionCounter, instructionRegister, operationCode, and operand, so that we can carry operations on them
Return value(s): returns 1 if it compiles succesfully otherwise it would return a zero or terminate.
Partners: None
Description: This function reads in the file through it's pointer line by line and then converts it's data into 4 digit values, then they get stored into memory array. The function the proceeds to check for some compiling errors then it returns the result.
*/

int compile (FILE* fPointer , int memory [], int* instructionCounter , int* instructionRegister ,int*operationCode ,int* operand){
    char s[80]; /* The buffer */
    *instructionRegister=0;
    *operationCode=0;
    while(((*instructionRegister)=fscanf(fPointer,"%d %s %d", operationCode,s,operand)) != EOF){ /*Reads data line by line then stores the integer returned by fscanf to instructionRegister pointer so that I can check for formating */
        if((*instructionRegister) ==3 ){ /*Checks for improper format by comparing the current instructionRegister count to 3, returns improper format otherwise */
            if(*operand >9999|| *operand <0){  /* Checks for word overflow in compiler, makes sure that digits do not exceed 9999 */
                printf("attempts to place a word in memory that is larger than 4 digits, or attempted to pass in a negative value\n ");
                exit(0);
            }
            /*Compares the string section of the code and checks if it matches the following words and then it converts it to it's 4 digit value by adding into it the operand */
            if(strcmp(s,"READ") == 0) {
                memory[*operationCode] = 10 * 100 + *operand;
            }
            else if(strcmp(s,"WRIT") == 0) {
                memory [*operationCode] = 11 * 100 + *operand;
            }
            else if(strcmp(s,"LOAD") ==0){
                memory [*operationCode] = 20 * 100 + *operand;
            }
            else if(strcmp(s,"PRNT") ==0){
                memory [*operationCode] = 12 * 100 + *operand;
            }
            else if(strcmp(s,"STOR") ==0){
                memory [*operationCode] = 21 * 100 + *operand;
            }
            else if(strcmp(s,"SET") ==0){
                memory [*operationCode] = *operand;
            }
            else if(strcmp(s,"ADD") ==0){
                memory [*operationCode] = 30 * 100 + *operand;
            }
            else if(strcmp(s,"SUB") ==0){
                memory [*operationCode] = 31 * 100 + *operand;
            }
            else if(strcmp(s,"DIV") ==0){
                memory [*operationCode] = 32 * 100 + *operand;
            }
            else if(strcmp(s,"MULT") ==0){
                memory [*operationCode] = 33 * 100 + *operand;
            }
            else if(strcmp(s,"MOD") ==0){
                memory [*operationCode] = 34 * 100 + *operand;
            }
            else if(strcmp(s,"BRAN") ==0){
                memory [*operationCode] = 40 * 100 + *operand;
            }
            else if(strcmp(s,"BRNG") ==0){
                memory [*operationCode] = 41 * 100 + *operand;
            }
            else if(strcmp(s,"BRZR") ==0){
                memory [*operationCode] = 42 * 100 + *operand;;
            }
            else if(strcmp(s,"HALT")==0){
                memory [*operationCode] =9999;
            }

            else {   /* Prints back to the user that the compiler did not recognize one of them commands as it was going through it */
                printf ("This is an unknown command, commands are case sensitive, program will now exit \n");
                exit(0);

            }
        }
        else{    /* Returns improper format if instructionRegister does not match 3*/
            printf("Improper Format, program will now exit \n");
            exit(0);
        }


    }
    /* Checks if the instruction data contains a HALT, if not it would terminate */
    while(*instructionCounter<100){
        if (memory[*instructionCounter] == 9999){
            return 1;
        }
        else
            (*instructionCounter)++;
    }
    printf("Halt was not found, program will now exit");    
    exit (0);

}
/*
Function Name       : execute
Parameters      : accumulator for storing in the arithematic operations , instructionCounter for counting the instructions, instructionRegisterfor storing the current instruction, 
operationCode stores the first 2 digits so that it would recognize what command is currently being executed, operand stores the next 2 digits , and the memory to be able to loop through the computer 100 memory
Return value(s)     : returns 1 if it executes fine, otherwise it would terminate if it finds an error. It also prints out HALT once found which shows the current state of the memory.
Partners            : None
Description     : This function processes the compiled instructions and start carrying out operations on them depending on their operation code, it also checks for error then it prints out the current memory state once it reaches HALT,
*/

int execute(int* accumulator ,  int* instructionCounter , int* instructionRegister ,int*operationCode ,int* operand, int memory [])
{
    /* Resets the values to zero because they were used in the compiler */
    *operand=0;
    *operationCode=0;
    *instructionRegister=0;
    *instructionCounter=0;
    *accumulator=0;

    /* this loop starts looking at the 4 digit memory cells and executes them 1 by 1  */
    while(*instructionCounter<100){

        checkWordFlow(*instructionCounter, memory);

        *instructionRegister=memory[*operand];  /*stores current instruction */

        *operand=memory[*instructionCounter]%100;   /* Stores the 2 right  digits  */

        checkSegmentationFault(operand);         /* checks that operand does not contain a negative value so that the problem does not throw a seg fault */

        *operationCode=memory[*instructionCounter]/100; /* Stores the 2 left diigts */

        if(*operationCode==10){ /*READ: inquires the user to provide input and stores it in specified address in the instructions*/

            scanf("%d",&memory[*operand]);

        }
        else if(*operationCode==11 ){ /*WRIT*: prints out the data in a memory element when executed*/
            printf("%d\n",memory[*operand]);
        }

        else if(*operationCode==12 ){ /*PRNT */

            while(1){   /*Loops and prints the followiing values that prnt passes in as operand */  

                /*Checks if the ASCI values are within the correct range */                
                if((memory[*operand]/100 > 65 &&memory[*operand]/100 <90)  || memory[*operand]/100 == 10 )
                    printf("%c",memory[*operand]/100);
                else if (memory[*operand]/100 == 0){
                    break;
                }
                else {
                    printf("Unknown Character\n");
                    exit(0);
                }
                if((memory[*operand]%100>65 &&memory[*operand]%100 <90)  || memory[*operand]%100 == 10)
                    printf("%c", memory[*operand]%100);
                else if (memory[*operand]%100 == 0){
                    break;
                }

                else{
                    printf("Unknown Character\n");
                    exit(0);
                }

                (*operand)++;  
            }
            *operand =0;  /*Resets the value of operand since it was incremented, so that it wont mess up the HALT print*/
            printf("\n");
        }
        else if(*operationCode==20 ){  /*LOAD : loads into the accumulator */
            *accumulator = memory[*operand];

        }
        else if(*operationCode== 21){  /*STORE: stores the accumlator value into the specific memory cell*/
            memory[*operand] = *accumulator;
        }

        else if(*operationCode==30 ){ /*ADD: adds into the accumulator the specificed memory address data*/
            *accumulator+=memory[*operand];
        }

        else if(*operationCode==31 ){ /*SUB: substracts from the accumulator the specified memoery addres data*/
            *accumulator= *accumulator - memory[*operand];
        }
        else if(*operationCode== 32){ /*DIV: divides from the accumulator the specificed memory address data */

            if(memory[*operand] >0){ /* Handles division by zero error */
                *accumulator= *accumulator/memory[*operand];
            }
            else {
                printf("Division by zero was attempted\n program will now exit \n");
                exit(0);
            }
        }
        else if(*operationCode== 33){    /*MULT: multiplies to the accumulator the specified address data*/
            *accumulator= *accumulator*memory[*operand];
        }   
        else if(*operationCode== 34){  /*MOD: calculates the remainder to the accumulator the specified address data*/
            *accumulator= *accumulator%memory[*operand];
        }
        else if(*operationCode ==40){  /*BRAN: jump memory execution to address given */
            *instructionCounter= *operand;
            (*instructionCounter)--;  /* deduct counter by 1 so that the loop does not skip over instructions */
        }
        else if(*operationCode ==41){ /*BRNG: jumps memory execution to addres given only if accumulator is negative*/

            if (*accumulator <0){        
                *instructionCounter=*operand;
                (*instructionCounter)--;  /* deduct counter by 1 so that the loop does not skip over instructions */

            }
        }
        else if(*operationCode ==42){  /*BRZR jumps memory execution to memory location only if accumulator is zero*/

            if(*accumulator ==0){        
                *instructionCounter=*operand;
                (*instructionCounter)--; /* deduct counter by 1 so that the loop does not skip over instructions */            
            }
        }
        else if(*operationCode == 99){  /*HALT: terminates the program but prints out the memory state before it does that*/
            printMemory(accumulator,instructionCounter,instructionRegister,operationCode,operand,memory); /*prints the memory out */
            exit(0);
        }
        else if(*operationCode == 0){ /* Checks for empty elements and moves passt them */
            (*instructionCounter)++;
            continue;
        }

        else{  /* Handles unrecognized operation codes */    
            printf("Unknown Command, program will now exit\n");
            exit(0);
        }

        (*instructionCounter)++;  /* Increment loop by 1 and start the next round of looping */

    }
    return 1;
}
int main (int argc, char* argv[]){
    FILE * fPointer=NULL;
    char fileName[150];
    int accumulator=0;
    signed int instructionCounter=0;
    signed int instructionRegister=0;
    int operationCode=0;
    int operand=0;
    signed int memory [100];
    /*Checks if the user passed in an argument at the command  line*/
    if(argc < 1){
        puts("You didn't specify the arguments or parameters\n");
        exit(0);

    }
    /*fill the buffer */
    if(argc>1)
        strcpy(fileName,argv[1]);


    fPointer=stdin;
    /* If file failed to open then this would throw an error */
    if(fPointer == NULL){
        puts("File failed to open\n");
        exit(0);
    }

    /* This loop fills the memory array with zeros*/
    for(instructionCounter =0;instructionCounter<100;instructionCounter++){
        memory [instructionCounter] = 0; 
    }
    instructionCounter=0;


    /* Run the commands */

    compile(fPointer, memory,&instructionCounter,&instructionRegister,&operationCode,&operand);
    execute(&accumulator,&instructionCounter,&instructionRegister,&operationCode,&operand,memory);
    return 1;
}

/*
   Function Name       : printMemory
Parameters      : accumulator, instructionCounter, instructionRegister, operationCode, operand, memory array, to insure that we print out the correct state of the memory we have to pass them in 
Return value(s)     : returns 1, but prints out memory state before it does that
Partners            : None
Description     : Prints out the current state of the memory in a nicely formatted manner
*/

int printMemory(int* accumulator , int* instructionCounter , int* instructionRegister ,int*operationCode ,int* operand, int memory []){
    printf("REGISTERS:\naccumulator              %+05d\ninstructionCounter          %02d\ninstructionRegister      %+05d\noperationCode               %02d\noperand                     %02d\n",
            *accumulator, *instructionCounter, *instructionRegister, *operationCode, *operand); 
    *instructionCounter =0;

    printf("MEMORY:\n       0     1     2     3     4     5     6     7     8     9\n");
    for((*instructionCounter)=0;(*instructionCounter)<100;(*instructionCounter)+=10) /* loops through the memory array and outputs 10 elements in every row */
    {
        printf("%2d",*instructionCounter);
        printf(" %+05d %+05d %+05d %+05d %+05d %+05d %+05d %+05d %+05d %+05d\n", memory[*instructionCounter], memory[*instructionCounter+1] , memory [*instructionCounter+2] , memory [*instructionCounter+3], memory[*instructionCounter+4],
                memory[*instructionCounter+5],memory[*instructionCounter+6],memory[*instructionCounter+7],memory[*instructionCounter+8],memory[*instructionCounter+9] );

    }
    return 1;
}
/*
   Function Name       : checksegmentationFault
Parameters      : operand.
Return value(s)     : returns 0, terminates the program if it tried to access an unknown operand , likely a negative value.
Partners            : None
Description     : terminates the program if it tried to access an unknown operand , likely a negative value.,
*/

int checkSegmentationFault(int *operand)
{
    if(*operand < 0 || *operand >100){
        printf("SEGMENTATION FAULT: Attempted to access an unknown address \n");
        exit(0);
    }
    return 0;
}
/*
   Function Name       : checkWordFlow
Parameters      : instructionCounter for looping, and memory array
Return value(s)     : 1 , terminates if it reaches a word overflow
Partners            : None
Description     : this function checks for the word overflow possible error at execution by checking that digit values do no surpass 9999,
*/

int checkWordFlow( int instructionCounter, int memory []) /*fix this shit */
{
    instructionCounter=0;
    while(instructionCounter<100){
        if(memory[instructionCounter]>9999)
        { printf("Word Overflow at memory element %d\n program will exit\n", instructionCounter);
            exit(0);
        }
        instructionCounter++;
    }
    return 1;
}

The stream of input looks something like this: (Like I mentioned above this stream is being redirected with a VIM command, it cheats the program into reading from files without having to actually implement file pointers)

01 READ 60
02 LOAD 60
03 SUB 61
04 STOR 60
05 BRNG 15
06 READ 70
07 LOAD 70
08 ADD 80
09 STOR 80
10 LOAD 60
11 SUB 61
12 STOR 60
13 BRNG 15
14 BRAN 6
15 WRIT 80
16 HALT 99
61 SET 1
80 SET 0

I've been scratching my head for hours and I cannot figure out why it's doing that, as I said I'm new to C programming and I still don't know how to debug and do the C stuff, I came from a Java background.

Edit 1: The user does not write the program to the virtual computer, the programs are already written and the user just redirects with a STDIN via a command in VIM like this (./computer < prog1) or (./computer < prog2). The program should compile successfully, and then when the computer figures out what kind of a program it is , it will prompt the user for input depending on it's task. So it could ask the user to input values , then it would calculate their average if that was the program that was redirected to it.

解决方案

If you are taking the input from the user, then the code will be different.

There are a few options,

  1. Keep the same code, but put a condition on the user to press Ctrl-Z after entering all the data. This will only work if you are the only person entering the data, and is generally not workable.

  2. After every loop, you can ask the user if he wants to enter more data. Then you can get the input as a y/n and loop back if the user enters y.

An example is below.

do
{
  scanf("%d %79s %d",operationCode,s,operand));
  // Other code here

   printf("\n Do you want to enter another value (y/n) ");
   scanf(" %c",&check);
} while(check != 'n");

  1. Loop for a fixed no of times, but your original code does not work that way and this will not be a good option for you.

这篇关于函数溢出错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆