Hatena::Groupcprogramming

C Study Diary

2008-12-03

c2ex6_setbits.cpp

16:13

Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.


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

unsigned setbits(unsigned x,int p, int n, unsigned y){
	
	return (x&(~(~0<<(p+1-n))|(~0<<(p+1)))|((y&(~(~0<<n)))<<(p+1-n)));
}

int main(void)
{
  unsigned i;
  unsigned j;
  unsigned k;
  int p;
  int n;
  /* test data from book */
  for(i = 0; i < 30000; i += 511)
  {
    for(j = 0; j < 1000; j += 37)
    {
      for(p = 0; p < 16; p++)
      {
        for(n = 1; n <= p + 1; n++)
        {
          k = setbits(i, p, n, j);
          printf("setbits(%u, %d, %d, %u) = %u\n", i, p, n, j, k);
        }
      }
    }
  }
  return 0;
}

Run:

$ ./c2ex6_setbits.exe
....
setbits(1022, 12, 4, 518) = 3582
setbits(1022, 12, 5, 518) = 1790
setbits(1022, 12, 6, 518) = 894
setbits(1022, 12, 7, 518) = 446
...
setbits(1022, 13, 9, 518) = 222
setbits(1022, 13, 10, 518) = 8302
setbits(1022, 13, 11, 518) = 4150
setbits(1022, 13, 12, 518) = 2074
setbits(1022, 13, 13, 518) = 1036
setbits(1022, 13, 14, 518) = 518
...
setbits(1022, 14, 8, 518) = 894
setbits(1022, 14, 9, 518) = 446
setbits(1022, 14, 10, 518) = 16606
setbits(1022, 14, 11, 518) = 8302
...
setbits(4088, 10, 2, 185) = 3064
setbits(4088, 10, 3, 185) = 2552
setbits(4088, 10, 4, 185) = 3320
setbits(4088, 10, 5, 185) = 3704
...

c2ex4_squeeze_string.cpp

20:05

Write an alternate version of squeeze(s1,s2) that deletes each character in the string s1 that matches any character in the string s2 .

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

void squeeze(char*,char*);


int main(){

	int i;
	char s1[100], s2[100];
	printf("input string s1(char appears in s2 will be removed from s1): \n");
	gets(s1);
	printf("input string s2: \n");
	gets(s2);
	printf("the two strings are %s, %s\n",s1,s2);
	squeeze(s1,s2);
	printf("after squeeze s1=%s\n",s1);
	

}
 
void squeeze(char* s1,char* s2){
	
	int i,j,k, len;
	/* for each char in s2*/
	for(i=0;i<strlen(s2);i++){
		/* compare char in s1 with char s2 */
		for(j=0;j<strlen(s1);j++){
			if(s1[j]==s2[i]){
				len = strlen(s1);
				/* remove the matched char by move the char afterwards forward  */
				for(k=j;k<len;k++){
					s1[k]=s1[k+1];
				}
				/* as the current char in postion j is the one after matched char, so move back j */
				j--; 
			}
		}
		
	}
	
}

Run:

$ ./c2ex4_squeeze_string.exe
input string s1(char appears in s2 will be removed from s1):
wwwww
input string s2:
w
the two strings are wwwww, w
after squeeze s1=

$ ./c2ex4_squeeze_string.exe
input string s1(char appears in s2 will be removed from s1):
abdcdddd
input string s2:
dc
the two strings are abdcdddd, dc
after squeeze s1=ab

c2ex3_htoi.cpp

15:17

Write the function htoi(s) , which converts a string of hexadecimal digits (including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0 through 9, a through f, and A through F .

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

unsigned long int htoi(char*);

int main(){
	
	unsigned long int result;
	int i;
	char *test[] =
	  {
	    "F00",
	    "bar",
	    "0100",
	    "0x1",
	    "0XA",
	    "0X0C0BE",
	    "abcdef",
	    "123456",
	    "0x123456",
	    "deadbeef",
	    "zog_c"
	  };

	for(int i=0;i<11;i++){
		result=htoi(test[i]);
		printf("%s equals to %lu\n",test[i],result);
	}
}

unsigned long int htoi(char* s){
	
	unsigned long int answer=0;
	unsigned int i=0; 
	
	if(s[i]=='0') i++;
	if(s[i]=='x' ||s[i]=='X') i++;
	
	while(s[i]!='\0'){
	/* 0-9 */
			if(s[i]>=48&&s[i]<=57){
				answer+=pow(16,strlen(s)-i-1)*(s[i]-'0');
				i++;
			}	
	/* A-F */		
			else if(s[i]>=65&&s[i]<=70){
				answer+=pow(16,strlen(s)-i-1)*(s[i]-'A'+10);  //a=10
				i++;
			}
	/* a-f */				
			else if(s[i]>=97&&s[i]<=102){
				answer+=pow(16,strlen(s)-i-1)*(s[i]-'a'+10);  //A=10
				i++;
			}		
	/* other */		
		 	else {
				printf("%s is not hex number.\n",s);
				return 0;
			}
	}
	return answer;
	
}

Run:

$ ./exe/c2ex3_htoi.exe
F00 equals to 3840
bar is not hex number.
bar equals to 0
0100 equals to 256
0x1 equals to 1
0XA equals to 10
0X0C0BE equals to 49342
abcdef equals to 11259375
123456 equals to 1193046
0x123456 equals to 1193046
deadbeef equals to 3735928559
zog_c is not hex number.
zog_c equals to 0

ex24_c_syntax_check.cpp

17:28

Write a program to check a C program for rudimentary syntax errors like unbalanced parentheses, brackets and braces. Don't forget about quotes, both single and double, escape sequences, and comments. (This program is hard if you do it in full generality.)

This program can check {},[],(),"" and '', but doesn't consider file with Comment.


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

#define MAX 100

enum{
 FOUND=1,
 SQUOTE,     //"
 CQUOTE      //'
};

typedef struct int_stack{
	int *top;
	int *bottom;
}INT_STACK;
  
void stack_ini(INT_STACK*);
int stack_pop(INT_STACK*);
int stack_push(int,INT_STACK*);
int check_syntax(FILE*);
int pair_char(int, int);
int print_warning(int,int);
int find_syntax_error(int,int);

INT_STACK sstack;
INT_STACK lstack;

int main(int argc, char* argv[]){
	
	char *input;
	FILE *fp1;
	
 	if(argc!=2) {
		printf("Error input. Format: syntaxcheck inputfile\n");
		return -1;
	}
	input=argv[1];
	/* open input file */
	if((fp1=fopen(input,"r"))!=NULL){	
		if(check_syntax(fp1)!=FOUND){
			printf("No rudimentary syntax error found.\n");
		}
		fclose(fp1);
	}
	else{
		printf("cannot open input file.\n");
	}

}

int check_syntax(FILE* file){
	
	int this_char, line=0, result=0, flag=0, temp_pop, temp_line;
	
	stack_ini(&sstack);
	stack_ini(&lstack);
	
	while((this_char=fgetc(file))!=EOF){
		/* count line number */
		if(this_char=='\n') {
			line++;
			flag=0;
		}	
		/* left  marks - push to stack */
		if(this_char=='{' || this_char=='[' || this_char=='(') {
			stack_push(this_char,&sstack);
			stack_push(line,&lstack);
		}	
		/* right marks - pop stack & compare */
		if(this_char=='}' || this_char==']'|| this_char==')') {

			result=find_syntax_error(this_char, line);
			
		}
		/* '  */
		if(this_char=='\''){
			if(flag!=CQUOTE){			
				stack_push(this_char,&sstack);
				stack_push(line,&lstack);
				flag=CQUOTE;
			}
			else{
				result=find_syntax_error(this_char, line);
				flag=0;
			}
		}
		/* " */
		if(this_char=='"'){
			if(flag!=SQUOTE){			
				stack_push(this_char,&sstack);
				stack_push(line,&lstack);
				flag=SQUOTE;
			}
			else{
				result=find_syntax_error(this_char, line);
				flag=0;
			}
		}
		/* if ; encountered, than check stacked quote marks */
		if(this_char==';'&&(flag==SQUOTE||flag==CQUOTE)){
			
			while((temp_pop=stack_pop(&sstack))=='\''||temp_pop=='"'){
				temp_line=stack_pop(&lstack);
				print_warning(temp_pop,temp_line);
				result=FOUND;
				temp_pop=0;
			}	
			if(temp_pop!=0){
				stack_push(temp_pop,&sstack);
			}	
		}
	}
	/* if marks left in stack when file ends*/
	while(sstack.top!=sstack.bottom){
		print_warning(stack_pop(&sstack),stack_pop(&lstack)+1);
		result=FOUND;			
	}
	return result;
}

/* find syntax error */
int find_syntax_error(int this_char, int this_line){

	int  pop_char, pop_line;

	if((pop_char=stack_pop(&sstack))!=-1){
		pop_line=stack_pop(&lstack); 
		if(pair_char(pop_char,this_char)!=1) {
			print_warning(pop_char,pop_line+1); 
			find_syntax_error(this_char, this_line);
			return FOUND;
		}else return 0;	
	}
	else {
		print_warning(this_char,this_line+1); 
		return FOUND;
	}
}
/* check if the marks are in pair */
int pair_char(int char1, int char2){
	
	switch(char1){
		case '{': if(char2=='}') return 1; else return -1;
		case '(': if(char2==')') return 1; else return -1;
		case '[': if(char2==']') return 1; else return -1;
		case '\'': if(char2==char1) return 1; else return -1;
		case '"': if(char2==char1) return 1; else return -1;
		default: printf("char:%c is not supported.\n",char1); return -1; 
	}
}
/* print warning */
int print_warning(int errorchar, int line){
	
	switch(errorchar){	
		case '{': printf("Line %d: Syntax Error: { missing }\n",line); return 1; 
		case '(': printf("Line %d: Syntax Error: ( missing )\n",line); return 1; 
		case '[': printf("Line %d: Syntax Error: [ missing ]\n",line); return 1; 
		case '}': printf("Line %d: Syntax Error: } missing {\n",line); return 1; 
		case ')': printf("Line %d: Syntax Error: ) missing (\n",line); return 1; 
		case ']': printf("Line %d: Syntax Error: ] missing [\n",line); return 1; 
		case '\'': printf("Line %d: Syntax Error: ' missing ' \n",line); return 1; 
		case '"': printf("Line %d: Syntax Error:  \"missing \"\n",line); return 1; 
		default: printf("error char:%c is not supported.\n",errorchar); return -1; 
	}

}
/* initiate stack  */
void stack_ini(INT_STACK *stack){
	stack->bottom=(int*)malloc(MAX*sizeof(int));	
	stack->top=stack->bottom;
}
/* pop */
int stack_pop(INT_STACK *stack){

	if(stack->top!=stack->bottom){
		stack->top--;
		return *stack->top;
	}
	else{
		//printf("nothing to pop");
		return -1;
	}
}
/* push */
int stack_push(int element,INT_STACK *stack){
	if(stack->top!=stack->bottom+MAX-1){
		*stack->top=element;
		stack->top++;
	}
	else {
		printf("stack is full!\n");
		return -1;
	}
}

Run:

$ ./exe/ex24_syntaxcheck.exe ex23_removed.cpp
Line 22: Syntax Error: ' missing '
Line 22: Syntax Error:  "missing "
Line 29: Syntax Error:  "missing "
Line 32: Syntax Error: ( missing )
Line 54: Syntax Error:  "missing "
Line 51: Syntax Error: ( missing )
Line 58: Syntax Error: } missing {

lymanlyman2008/12/04 17:00so complicated ...

lymanlyman2008/12/04 17:11htoi 的话,用倒循环比较好,这样就省得算strlen() + 什么 - 什么那一堆了。

btw, this day-based blog system sucks.

JasonerakyJasoneraky2017/01/25 04:24изготовление открыток под заказ http://wkrolik.com.ua/products/knigi