【原创】自制编程语言-6 输入语句
现在我们的编程语言功能越来越多了,干劲也更足了,趁着这势头,我们继续写下去吧。这次我们来尝试编写输入语句。有了一个功能,加上运算符,我们就可以实现A+B问题了,真不错。输入语句的样式用很多,例如:
C++:cin>>a;
C:scanf("%d",&a);
PASCAL:read(a)
PYTHON:a=input()
我们就使用PYTHON的方式吧。这样写起来可以和赋值语句结合在一起。我们的输入就写成这样:
a = input()
好了,开始编写代码。关键点在于,我们如何从屏幕进行读入。因为之前为了读取代码,我们使用了freopen修改了读入的默认对象stdin。所以,我们需要重新将读入流修改回控制台。
有的人会问,“除了freopen,还有什么方式可以修改文件流?老师只说过这一种方法,还说其它的方式没必要知道那么多,知道一个freopen就够了。”现在看来,这个完全是错误的。(当然,如果是编程竞赛而不是工程设计,一个freopen是完全足够的)
C++可以用fstream来实现,C语言可以用FILE*指针实现。这里为了简单一点,我们直接用fstream实现了。
ifstream cons("CON")表示制作一个叫做cons的输入流,输入目标文件为"CON",实际就是将输入文件设置为控制台,就可以从控制台输入数据。此时就可以用cons>>n的语句来从cons读入。cons其实就是之前定义的变量。
多说一句, 这里的ifstream不是一个函数,而是构造函数。更多关于构造函数的知识可以去网上搜索。笔者这里的自制string类型以后也可能会往里面放一些构造函数和析构函数的东西。(不过可能会咕一阵子)
好了,我们尝试运行A+B PROBLEM的代码。激动人心的时刻到了。(笑)
话说print不可以连续输出很不方便,到时候抽时间改掉就是了。但是这还不是最难受的,最难受的在于,1和2中间必须使用换行符分割。(如果想知道用空格会发生什么,自己运行一下吧)
所以,我们需要查错误。其实只需要移动一行代码就解决了。
没错,把cons设定为全局变量。
完。附上完整版代码。
- #include<bits/stdc++.h>
- using namespace std;
- char s[100];
- ifstream cons("CON");
- struct VALUE{
- char name[30];//变量名
- int type;//类型,0表示int,1表示string
- int vnum;//int类型的数值
- char vstring[255];//string类型
- };
- int value_ptr=0;
- struct VALUE value[1000];
- void get_word(char *s){//读入单词
- scanf("%s",s);
- }
- void get_string(char *s){
- int i=0,flag=0;
- for(i=0;i<100;i++){
- next:
- s[i]=getchar();
- if(flag==0 && s[i]==' ')goto next;
- else flag=1;
- if(s[i]=='\n')break;
- }
- s[i]='\0';//结束掉字符串
- }
- void error(){
- cout<<"Error in program.\n";
- exit(0);//退出程序
- }
- int isnumber(const char *s){
- for(int i=0;i<strlen(s);i++)
- if(s[i]<='0' || s[i]>='9')return 0;//不是数字字符
- return 1;
- }
- int isvalue(const char *s){
- for(int i=0;i<value_ptr;i++){
- if(strcmp(value[i].name,s)==0)return 1;
- }
- return 0;
- }
- int getpos(const char *vname){
- for(int i=0;i<value_ptr;i++){
- if(strcmp(value[i].name,vname)==0)return i;//下标
- }
- return -1;//未找到
- }
- void put_value(const char *name){
- int i=getpos(name);
- if(i==-1)error();
- if(value[i].type==0)printf("%d",value[i].vnum);
- else printf("%s",value[i].vstring);
- }
- int getnum_sub(const char *s){
- if(isvalue(s))return value[getpos(s)].vnum;//是变量
- int i;
- sscanf(s,"%d",&i);
- return i;//是数字
- }
- int getnum(const char *s){
- if(strcmp(s,"input()")==0){
- int n;
- cons>>n;
- return n;
- }
- char *p;
- char op;
- for(p=(char*)s;*p!='+'&&*p!='-'&&*p!='*'&&*p!='/'&&*p!='\0';p++);//找到运算符
- if(*p=='\0')return getnum_sub(s);//只有一个数的情况
- op=*p;*p='\0';//第一个数字到运算符结束
- char s1[100],s2[100];
- int n1,n2;
- strcpy(s1,s);strcpy(s2,p+1);
- n1=getnum_sub(s1);n2=getnum_sub(s2);
- if(op=='+')return n1+n2;
- else if(op=='-')return n1-n2;
- else if(op=='*')return n1*n2;
- else if(op=='/')return n1/n2;
- }
- int main(int argc,char** argv){
- if(argc!=2){//有一个要解释的文件参数
- cout<<"Cannot find source file.\n";
- return 0;
- }
- freopen(argv[1],"r",stdin);
- for(;;){
- get_word(s);
- if(strcmp(s,"print")==0){//调用print输出
- get_string(s);
- if(isnumber(s))cout<<s;
- else if(s[0]=='\"' && s[strlen(s)-1]=='\"'){
- for(int i=1;i<strlen(s)-1;i++){
- if(s[i]=='\\' && s[i+1]=='n'){
- printf("\n");i++;
- }
- else printf("%c",s[i]);
- }
- }
- else if(isvalue(s)){
- put_value(s);
- }
- else error();
- }
- else if(strcmp(s,"exit")==0){//退出程序
- return 0;
- }
- else if(strcmp(s,"dim")==0){//声明变量
- char sa[255],sb[255],sc[255];
- get_word(sa);get_word(sb);get_word(sc);
- if(strcmp(sb,"as")!=0)error();
- strcpy(value[value_ptr].name,sa);
- if(strcmp(sc,"int")==0)value[value_ptr].type=0;
- else if(strcmp(sc,"string")==0)value[value_ptr].type=1;
- else error();
- value_ptr++;
- }
- else if(isvalue(s)){//变量的赋值语句
- char sa[255],sb[255];
- get_word(sa);get_string(sb);
- if(strcmp(sa,"=")!=0)error();
- if(value[getpos(s)].type==0)value[getpos(s)].vnum=getnum(sb);
- else {
- sb[strlen(sb)-1]='\0';//去掉最后的双引号
- strcpy(value[getpos(s)].vstring,sb+1);//复制的时候去掉前面的双引号
- }
- }
- else{
- error();
- }
- }
- }
赞 (0)