记录一个找了好久解决了的问题,附原链接:
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3688056&ordertype=1?%ra=link
以下内容为复制的原博主的内容:
最近在练习写一个微型编译器:int memory[100] 中的每一个元素用来存放一个指令或者一个数据。现在遇到个问题是如何放置一个字符串,书上给了提示:数组的每一个元素可以分成两组,每一组包含两位数字的整数。每一个数组元素中的半个元素储存的是字符串中字符的个数(即字符串长度),后续的每一个半元素储存的是一个字符的以两位十进制数表示的ASCII码。具体我想的应该是下面这样:
这本书比较久远,并没有说明int 是占几个字节有个疑问是:一个int(4byte)能不能放下一个字符。想了好久还是没有思路,求大家指点下。
暂时只能想到这里:
char str[50]; //临时储存字符串
int i=0; //统计字符串长度
int first;
for( ; (str = getchar()) !=‘\n’; i++);
i<<=16;
i |= str[0];
memory[index] = i; //这里该怎么做{:3_198:}
已经实现了,没有依照书上给的提示来。第一个int的前2个字节储存字符串的长度,后2字节储存一个字符,后续的一个int储存2个字符。试了下中文也能实现。不过存在一个’\n’的问题。调用fgets()总是会把‘\n’也当成一个字符读入,例如输入"abc"回车,最后变成了"abc\n" 不知到最后的’\n’是怎么来的{:3_186:}
有什么好的办法能够清空标准输入中前面遗留的数据吗?
主函数中是这么调用的:
//memory为内存单元,operand为内存单元起始地址,str为缓冲区
case STRREAD: //从标准输入读字符串
getchar( ); //为了消除前面遗留的’\n’,很挫的写法。。
if( fgets( str, BUFFER, stdin ) != NULL ){ //这样还是会有一个’\n’读入到str中,该怎么办
stodigit( memory, operand, str );
++*instructionCounter;
}
break;
case STRWRITE: //从内存单元中取字符串
puts( digittos( memory, operand, str ) );
++*instructionCounter;
break;
//把缓冲区的数据储存到内存单元中,memory为内存单元,index为起始地址,str为缓冲区
void stodigit( int *memory, int *index, char *str ){
int len = strlen( str ); //获取缓冲区的长度
int pivot = len << 16; //储存至前2byte
char cha;
cha = str[0];
memory[*index] = pivot | cha; //储存至一个内存单元
++*index;
if( len > 1 ){
int i;
int height;
int low;
for( i = 1; i <= len - 1; i += 2 ){
height = str; //下一个内存单元的前2个byte
low = str[i + 1]; //下一个内存单元的后2个byte
height <<= 16;
memory[*index] = height | low; //组合2个字符并储存至内存单元中
++*index; //储存后下移一个内存单元
}
}
}
//解析内存单元中的字符串,放入缓冲区中。
char *digittos( int *memory, int *index, char *str){
int len;
char cha;
len = memory[*index] >> 16; //获得前2个byte,就是字符串长度
cha = memory[*index] & 0xFFFF; //获取后2个byte表示的第一个字符,
str[0] = cha;
++*index;
if( len > 1 ){
int i;
char height;
char low;
for( i = 1; i <= len - 1; i += 2 ){
height = memory[*index] >> 16; //重复拆分
str = height;
low = memory[*index] & 0xFFFF;
str[i+1] = low;
++*index;
}
}
if( str[len] != '\0' ){ //如果最后解析的low不是结束符,则加一个'\0'
str[len + 1] = '\0';
}
return str;
}