システムプログラミングコメント


2022~1システムプログラミング期間中試験準備作業総括

文字列の読み取り、lengthの出力、helloの入力まで続行します。

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

void main(){
	char x[10];

        while(1){
                printf("Enter a string\n");
                scanf("%s", x);
                printf("You entered %s. length=%d\n", x, strlen(x));

                if(strcmp(x,"hello")==0){
                        printf("Yes it is hello. Bye.\n");
                        break;
                }
                printf("No it is not hello\n");

        }
}
  • scanfと入力された単語
  • を保存します.
  • strcmpを使用して文字列
  • を比較する

    文字列を読み込み、特定の文字を別の文字に置き換えます。

    #include <stdio.h>
    #include <string.h>
    
    void main(){
    	char x[10];
        char y1[10];
        char y2[10];
        char y3[10];
        
        printf("Enter a string\n");
        scanf("%s", x);
        
        strcpy(y1, x);
        y1[0]='a';
        
        strcpy(y1, x);
        y2[0]='b';
        
        strcpy(y1, x);
        y3[0]='c';
        
        printf("After copying and changing the first letter\n");
        printf("%s %s %s\n", y1, y2, y3);
    }
    hello -> aello bello cello

    strcpy、scanfに関連するエラー

    char x[30];
    strcpy(x, "hello");
    // "hello"는 주소값으로 인식되기 때문에 바로 대입 불가능
    
    char *y;
    y="hello1"; // this is ok
    strcpy(y, "hello");
    // 포인터로 선언한 주소값을 받기 때문에 주소값 "hello1"은 받을 수 있지만
    // strcpy는 string이 복사되기 때문에 받을 수 없음
    // 포인터 대신 char y[10];으로 선언하면 strcpy를 통해 복사할 수 있음
    
    char *y;
    scanf("%s", y);
    // y는 주소값을 받는 포인터로 선언하였기 때문에 string을 받을 수 없다.

    「end」が表示されるまで文字列を読み取り続けるプログラムです。

    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	char* arr[100];
            int i=0;
    
            while(1){
                    printf("Enter a string\n");
                    arr[i] = new char[100];
                    scanf("%s",arr[i]);
                    if(strcmp(arr[i], "end")==0){
                            break;
                    }
                    i++;
            }
    
    	printf("Strings entered so far are\n");
            for(int j=0; j<i; j++){
                    printf("%s\n", arr[j]);
                    delete(arr[j]);
            }
    }
  • 文字列を受信する配列はchar pointerarray
  • である.
    各文字列はnew charによって
  • 動的に割り当てられる

    getとfgetsの違い

    fgetsを使用すると、もう1文字入力されます.
    すなわち、fgetsの入力が完了し、enterを押すとenter度の文字で入力を受け付ける

    strtok-文から単語を抽出

    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	char buf[256];
        char *token;
        printf("enter a sentence\n");
        fgets(buf, 255, stdin); // 문자를 입력 받음
    
        printf("You entered %s", buf);
        buf[strlen(buf)-1]=0; // 개행 문자 제거
    
        char origin[256];
        char words[256];
    
        strcpy(origin, buf);
        strcpy(words, buf);
    
        token = strtok(buf, " ");
        int count = 0;
        for(;;){
                count++;
                token = strtok(NULL, " ");
                if(token==NULL) break;
        }
    	printf("There were %d words:\n", count);
    
        token = strtok(words, " ");
        for(;;){
                printf("%s\n", token);
                token = strtok(NULL, " ");
                if(token==NULL) break;
        }
    
    	printf("The original sentence was: %s\n", origin);
    }

    入力した名前は配列に格納されます

    #include <stdio.h>
    #include <string.h>
    
    void main(){
    	char* arr[100];
            int i=0;
    
            while(1){
                printf("Enter a name\n");
                arr[i] = new char[100];
    
                fgets(arr[i], 100, stdin);
                arr[i][strlen(arr[i])-1]='\0';
    
                if(strcmp(arr[i], "bye")==0){
                            break;
                }
                i++;
            }
    
    	printf("There were %d names\n", i);
    
        for(int j=0; j<i; j++){
                printf("%s\n", arr[j]);
        }
    }

    長い文の中ですべての単語の頻度を求めて、最大の頻度

    algorithm:
    	read line
        tokenize
        display tokens
        compute frequency
        	display frequency
        compute max freguency word and display it
    	
    algorithml for compute frequency:
    	for each token
        if it is already in unique_tokens[] array, increase its frequency
        otherwise store in unique_tokens[] and initialize its frequency
    #include <stdio.h>
    #include <string.h>
    
    typedef struct frequen_y fre;
    struct frequenc_y{
    	char* tok;
        int frequency_r;
    }
    
    // 문자열을 받고 받은 문자열을 출력
    void show(char buf[]){
    	printf("Enter a sentence\n");
        fgets(buf, 500, stdin);
        buf[strlen(buf)-1]=0;
        printf("you entered %s\n", buf);
    }
    
    // 띄어쓰기 당 글자 수를 세고 그 글자들을 각각 출력
    void tokenize(char buf[], char *tokens[]){
    	char* k;
        int j;
        k=strtok(buf," ");
        int cnt=0;
        
        for(;;){
        	if(k==NULL) break;
            tokens[cnt]=k;
            cnt++;
            k=strtok(NULL, " ");
        }
        
        printf("There were %d words:",cnt);
        for(j=0;j<cnt;j++){
        	printf("%s ", tokens[j]);
        }
        
        printf("\n");
    }
    
    // 띄어쓰기 당 글자의 빈도수를 찾는 함수
    void frequency(char *tokens[], fre freq[]){
    	int i=0;
        int j=0;
        int count=0;
        
        while(tokens[i] != NULL){
        	for(j=0;j<count;j++){
            	if(strcmp(tokens[i], freq[j].tok)==0){
                	freq[j].frequency_r++;
                    break;
                }
            }
            
            if(j>=count){
            	freq[count].tok=tokens[i];
                freq[count].frequency_r=1;
                count++;
            }
            
            i++;
        }
        
        for(i=0;i<count;i++){
        	printf("%s %d", freq[i].tok, freq[i].frequency_r);
        }
    }
    
    // 가장 많이 나오는 글자를 찾는 함수
    void maxfrequency(fre freq[]){
    	int i=0;
        int max_count=0;
        int max=freq[0].frequency_r;
        
        while(freq[i].frequency_r>0){
        	if(freq[i].frequency_r > max){
            	max = freq[i].frequency_r;
                max_count = i;
            }
            
            i++;
        }
        
        printf("\nThe word with the max freq:%s\n", freq[max_count].tok);
    }
    
    void main(){
    	char buf[500];
        char *token[500];
        fre frequency_s[500];
        
        show(buf);
        tokenize(buf, token);
        
        frequency(token, frequency_s);
        maxfrequency(frequency_s);
    }

    バイトサイズの検索


    :ls -l (파일명)を使用

    ファイルの内容を別のファイルにコピー

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	int x1, x2, y;
            char buf[50];
    
            x1=open("hw4.c",O_RDONLY, 00777);
            // O_CREAT | O_TRUNC - 파일이 없으면 생성, 있으면 덮어쓰기
            x2=open("cphw4.c", O_RDWR | O_CREAT | O_TRUNC, 00777);
            for(;;){
                    y=read(x1, buf, 20);
                    if(y==0) break;
                    write(x2, buf, y);
            }
    	return 0;
    }

    ファイル名の受信とコピー

    
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	int x1, x2, y;
            char buf[50];
    
            char fname[50];
            char dfname[50];
    
            printf("Enter src file name\n");
            scanf("%s", fname);
    
            printf("Entere dest file name\n");
            scanf("%s", dfname);
    
            x1=open(fname,O_RDONLY, 00777);
            x2=open(dfname, O_RDWR | O_CREAT | O_TRUNC, 00777);
            for(;;){
                    y=read(x1, buf, 20);
                    if(y==0) break;
                    write(x2, buf, y);
            }
    	printf("%s is copied into %s successfully.\n", fname, dfname);
            return 0;
    }

    mycat

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	int x, y;
            char buf[50];
    
            char fname[50];
    
            printf("Enter file name\n");
            scanf("%s", fname);
    
            char tmp[256];
            printf("The content of %s is:\n", fname);
    
            x=open(fname,O_RDONLY, 00777);
            for(;;) {
                    y=read(x, buf, 20);
                    if(y==0) break;
                    printf("%s", buf);
            }
    
    	return 0;
    }
    

    myxxd

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	int x, y;
            unsigned char buf[50];
    
            char fname[50];
    
            printf("Enter file name\n");
            scanf("%s", fname);
    
            char tmp[256];
            printf("The content of %s is:\n", fname);
    
            x=open(fname,O_RDONLY, 00777);
            for(;;) {
                    y=read(x, buf, 1);
                    if(y==0){
                            printf("\n");
                             break;
                    }
                    printf("%x ", buf[0]);
            }
    
    	return 0;
    }

    ファイルを3つのサイズに近いファイルに分割

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(){
    	char fname[256];
        int fd, fd2;
        struct stat fs;
        int fileinfo;
        int fsize;
        char *newname;
        char *buf;
        int y;
        
        printf("Enter file name to split\n");
        fgets(fname, 255, stdin);
        fname[strlen(fname)-1]=0;
        
        fd=open(fname, O_RDONLY, 00777);
        if(fd<0){
        	perror("Error");
            return -1;
        }
        fstat(fd, &fs); // 파일 사이즈 추출
        fsize = fs.st_size;
        
        int piece = fsize / 3;
        int remainder = fsize % 3;
        
        printf("%s is split into ", fname);
        for(int i=0;i<3;i++){
        	newname = new char[strlen(fname)+1];
            strcpy(newname, fname);
            newname[strlen(newname)] = i+49; // 파일명 뒤에 인덱스 추가
            printf("%s ", newname);
            fd2 = open(newname, O_RDWR | O_CREAT | O_TRUNC, 00777);
            if(i==0){
            	buf = new char[piece+remainder];
                y = read(fd, buf, piece+remainder);
                write(fd2, buf, piece+remainder);
           }
           else{
           		buf = new char[piece];
                y = read(fd, buf, piece);
                write(fd2, buf, piece);
           }
        }
        printf("\n");
        return 0;
    }

    swvader03.wavの内容を分析する

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    
    void main(){
    	char ChunkID[10];
    	int ChunkSize;
    	char Format[10];
    	char Subchunk1ID[10];
    	int Subchunk1Size;
    	short AudioFormat;
    	short NumChannels;
    	int SampleRate;
    	int ByteRate;
    	short BlockAlign;
    	short BitsPerSample;
    	char Subchunk2ID[10];
    	int Subchunk2Size;
    
    	int x, y;
    
    	x=open("./swvader03.wav",O_RDONLY, 00777);
    	y=read(x, ChunkID, 4);
    	ChunkID[y]=0;
    
    	y=read(x, &ChunkSize, 4);
    
    	y=read(x, Format, 4);
    	Format[y]=0;
    
    	y=read(x, Subchunk1ID, 4);
    	Subchunk1ID[y]=0;
    	
    	y=read(x,&Subchunk1Size, 4);
    
    	y=read(x, &AudioFormat, 2);
    	
    	y=read(x, &NumChannels, 2);
    	
    	y=read(x, &SampleRate, 4);
    
    	y=read(x, &ByteRate, 4);
    
    	y=read(x, &BlockAlign, 2);
    
    	y=read(x, &BitsPerSample, 2);
    	
    	y=read(x, Subchunk2ID, 4);
    	Subchunk2ID[y]=0;
    
    	y=read(x,&Subchunk2Size, 4);
    	
    	printf("ChunkID: %s\n", ChunkID);
    	printf("ChunkSize: %d\n", ChunkSize);
    	printf("Format: %s\n", Format);
    	printf("Subchunk1ID: %s\n", Subchunk1ID);
    	printf("Subchunk1Size: %d\n", Subchunk1Size);
    	printf("AudioFormat: %d\n", AudioFormat);
    	printf("NumChannels: %d\n", NumChannels);
    	printf("SampleRate: %d\n", SampleRate);
    	printf("ByteRate: %d\n", ByteRate);
    	printf("BlockAlign: %d\n", BlockAlign);
    	printf("BitsPerSample: %d\n", BitsPerSample);
    	printf("Subchunk2ID: %s\n", Subchunk2ID);
    	printf("Subchunk2Size: %d\n", Subchunk2Size);
    }

    swvader03.wavの内容を分析+ファイルに保存

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdio.h>
    
    void main(){
    	char ChunkID[10];
    	int ChunkSize;
    	char Format[10];
    	char Subchunk1ID[10];
    	int Subchunk1Size;
    	short AudioFormat;
    	short NumChannels;
    	int SampleRate;
    	int ByteRate;
    	short BlockAlign;
    	short BitsPerSample;
    	char Subchunk2ID[10];
    	int Subchunk2Size;
    
    	int x, y;
    
    	x=open("./swvader03.wav",O_RDONLY, 00777);
    	y=read(x, ChunkID, 4);
    	ChunkID[y]=0;
    
    	y=read(x, &ChunkSize, 4);
    
    	y=read(x, Format, 4);
    	Format[y]=0;
    
    	y=read(x, Subchunk1ID, 4);
    	Subchunk1ID[y]=0;
    	
    	y=read(x,&Subchunk1Size, 4);
    
    	y=read(x, &AudioFormat, 2);
    	
    	y=read(x, &NumChannels, 2);
    	
    	y=read(x, &SampleRate, 4);
    
    	y=read(x, &ByteRate, 4);
    
    	y=read(x, &BlockAlign, 2);
    
    	y=read(x, &BitsPerSample, 2);
    	
    	y=read(x, Subchunk2ID, 4);
    	Subchunk2ID[y]=0;
    
    	y=read(x,&Subchunk2Size, 4);
    	
    	FILE *fout=fopen("sw2-wav.txt", "w");
    	fprintf(fout, "ChunkID: %s\n", ChunkID);
    	fprintf(fout, "ChunkSize: %d\n", ChunkSize);
    	fprintf(fout, "Format: %s\n", Format);
    	fprintf(fout, "Subchunk1ID: %s\n", Subchunk1ID);
    	fprintf(fout, "Subchunk1Size: %d\n", Subchunk1Size);
    	fprintf(fout, "AudioFormat: %d\n", AudioFormat);
    	fprintf(fout, "NumChannels: %d\n", NumChannels);
    	fprintf(fout, "SampleRate: %d\n", SampleRate);
    	fprintf(fout, "ByteRate: %d\n", ByteRate);
    	fprintf(fout, "BlockAlign: %d\n", BlockAlign);
    	fprintf(fout, "BitsPerSample: %d\n", BitsPerSample);
    	fprintf(fout, "Subchunk2ID: %s\n", Subchunk2ID);
    	fprintf(fout, "Subchunk2Size: %d\n", Subchunk2Size);
    }

    swvader03.wavフロントエンドのクリップ

    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    void main(){
    	int subchunk2_size;
    	
    	int x=open("sw2.wav", O_RDWR);
    	lseek(x, 40, SEEK_SET); // 데이터의 크기를 읽기 위함
    	
    	read(x, &subchunk2_size, 4);
    
    	int temp = subchunk2_size/2;
    	void* zero = malloc(temp);
    	memset(zero, 0, temp);
    	write(x, zero, temp);
    
    	free(zero);
    
    }

    swvader03.wavマスターを2回繰り返します

    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    void main(){
    	int subchunk2_size;
    	
    	int x=open("sw3.wav", O_RDWR);
    	lseek(x, 40, SEEK_SET);
    	
    	read(x, &subchunk2_size, 4);
    
    	int temp = subchunk2_size/2;
    	lseek(x, temp, SEEK_CUR);
    
    	void* y = malloc(temp);
    	read(x,y,temp);
    
    	lseek(x, 44, SEEK_SET); // 실제 사운드 데이터의 시작 부분
    	write(x, y, temp);
    
    	free(y);
    
    }

    myecho

    #include <stdio.h>
    
    void main(int argc, char* argv[]){
    	int i;
    	for(i=1;i<argc;i++){
    		printf("%s ", argv[i]);
    	}
    	printf("\n");
    }

    mycat with options

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <dirent.h>
    #include <string.h>
    
    void docopy(char *f1, char *f2);
    void doxxd(char *f);
    void showcontent(char *d);
    void showfiles(char *d);
    
    void main(int argc, char* argv[]){
    	int i;
    
    	int x,y;
    	char buf[20];
    
    	if(strcmp(argv[1], "-o")==0){
    		docopy(argv[2], argv[3]);
    	}
    	else if(strcmp(argv[1], "-x")==0){
    		doxxd(argv[2]);
    	}
    	else if(strcmp(argv[1], "-p")==0){
    		showcontent(argv[2]);
    	}
    	else if(strcmp(argv[1], "-d")==0){
    		showfiles(argv[2]);
    	}
    	else{ // 옵션이 없으면 단순 파일 읽기 명령어
    	        x=open(argv[1], O_RDONLY, 00777);
    		if(x==-1){
    			perror("error in open");
    			exit(1);
    		}
    		for(;;){
    			y=read(x, buf, 20);
    			if(y==0) break;
    			write(1, buf, y);
    		}
    	}
    }
    
    // 내용 복사
    void docopy(char *f1, char *f2){
    	int y;
    	char buf[20];
    
    	int x1=open(f1, O_RDONLY, 00777);
    	int x2=open(f2, O_WRONLY|O_CREAT|O_TRUNC, 00777);
    
    	if(x1==-1){
    		perror("error in open");
    		exit(1);
    	}
    	for(;;){
    		y=read(x1, buf, 20);
    		if(y==0) break;
    		write(x2, buf, y);
    	}
    }
    
    // 16진수로 출력
    void doxxd(char *f){
    	int x, y;
    	char buf[20];
    	x = open(f, O_RDONLY, 00777);
    	if(x==-1){
    		perror("error in open");
    		exit(1);
    	}
    	for(;;){
    		y=read(x, buf, 16);
    		if(y==0) break;
    		int i;
    		for(i=0;i<16;i++){
    			printf("%x ", buf[i]);
    		}
    		printf("\n");
    	}
    }
    
    void showcontent(char *d){
    	FILE* x=fopen(d, "r");
    	if(x==NULL){
    		perror("Fail to open");
    		exit(1);
    	}
    	const char* fields[] = { "name", ", password", ", UID", ", GID", ", GECOS", ", directory", ", shell" };
    	char line[100];
    	while(fgets(line, 100, x)!=NULL){
    		int i=0;
    		char* field=strtok(line,":");
    		while(field!=NULL){
    			printf("%s: %s", fields[i], field);
    			i++;
    			field=strtok(NULL, ":");
    		}
    	}
    	fclose(x);
    }
    
    // 디렉토리 내 파일 이름 출력
    void showfiles(char *d){
    	DIR *dir = opendir(d);
    	if(dir==NULL){
    		perror("failed to open directory");
    		exit(1);
    	}
    	struct dirent *de=NULL;
    	while((de=readdir(dir))!=NULL){
    		if(strcmp(de->d_name, ".")==0) continue;
    		if(strcmp(de->d_name, "..")==0) continue;
    		printf("%s ", de->d_name);
    	}
    	printf("\n");
    	closedir(dir);
    }
    

    mycat-複数のファイルを同時に処理

    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <dirent.h>
    #include <string.h>
    
    void docopy(char *f1, char *f2);
    void doxxd(char *f);
    void showcontent(char *d);
    void showfiles(char *d);
    
    void main(int argc, char* argv[]){
    	int i;
    	
        for(i=1<i<argc;i++){
        		int x,y;
    			char buf[20];
    			x=open(argv[i], O_RDONLY, 00777);
    			if(x==-1){
    				perror("error in open");
    				exit(1);
    			}
    			for(;;){
    				y=read(x, buf, 20);
    				if(y==0) break;
    				write(1, buf, y);
    			}
        }
    }