System programming Note

짱J·2022년 4월 16일
0

시스템프로그래밍

목록 보기
2/3
post-thumbnail

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 pointer array
  • 각 문자열은 new char를 통해 동적할당

gets와 fgets의 차이점

fgets 를 사용하는 경우 문자가 하나 더 입력됨
즉, 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, " "); // 첫 번째 strtok 사용
    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;
    }
	
    // 기존에 저장해두었던 origin 배열 사용
	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];
		
        // scanf는 공백이 있는 문자열을 받지 못하니 fgets를 사용하자
        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); // 최대 빈도수를 가지는 단어 출력
}

byte size 찾기

: 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;
}

무한루프 속에서,
1. read()
2. y==0 break
3. write()

파일 이름을 입력 받아서 복사


#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); // write 대신 printf 사용
        }

	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;
}

파일을 세 개의 크기가 비슷한 파일로 분리

#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(){
	// Code 1.
	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);
    
    // -----
    // Code 2.
    int subchunk2_size;
    int x, y, half_size;
    
    char buf[1];
    buf[0]=0;
    
	x=open("sw2.wav", O_RDWR);
	lseek(x, 40, SEEK_SET);
    y =read(x, &subchunk2_size, 4);
    half_size=subchunk2_size/2;
    
    for(int i=0;i<half_size;i++){
    	write(x, buf, 1);
    }

}

swvader03.wav master 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);
			}
    }
}

프로세스 관련 함수 정리

ps -f
ps -ef
getpid()
getppid()
x=fork(); - 반환 값이 0이면 자식 프로세스, 0이 아니라면 부모 프로세스이다. (자식 프로세스 번호를 출력)

profile
[~2023.04] 블로그 이전했습니다 ㅎㅎ https://leeeeeyeon-dev.tistory.com/

0개의 댓글