리눅스 과제 질문이요ㅠㅠ

wkfdlek의 이미지

환경: ubuntu

cont.c 소스(이름은 그냥 손잡히는대로 쓴겁니다)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "student.h"
 
 
int main(int argc, char *argv[])
{
	int fd, id, k = 99, cnt = 0, ret = 0;
	char s = 121, na[MAX] , fn[MAX], c = 0;
	char ad[3] = "A+", a[3] = "A", bd[3] = "B+",b[3] = "B",cd[3] = "C+",c_[3] = "C",dd[3] = "D+",d[3] = "D", f[3] = "F";
	struct student record;
	struct flock lock;
 
 
	if (argc < 2) {
		fprintf(stderr, "사용법 : %s file \n", argv[0]);
		exit(1);
	}
	//fd = open(argv[1], O_RDWR);
	fd = open(argv[1], O_RDWR,0644);//|O_CREAT, 0644);//|O_EXCL, 0640);
	if (fd == -1) {
		perror(argv[1]);
		exit(2);
	}
 
	while(k>4 || k<0){
		printf("%d\n\n",fd);
		if(k != 99) printf("\n번호를 잘못 입력하셨습니다. 다시 입력하시오\n");
		printf("\n학생 데이터 관리 프로그램\n0.학생 목록 보기\n1.학생 정보 삽입\n2.학생 정보 보기(이름)\n3.장학금 수정\n4.학생 데이터 삭제\n\n번호 선택(0~4) : ");
		scanf("%d",&k);
 
	//학생 목록 보기
	if(k == 0){
		id = 1;
		while (id <= START_ID) {
			lseek(fd, (id - START_ID) * sizeof(record), SEEK_SET);
			if ((record.del != 0) && (record.id != 0))
				if((read(fd, (char *)&record, sizeof(record)) > 0))
				printf("이름:%s\t 학번:%d\t 점수:%d\t 학점:%s\t 장학금:%d\t 전화번호:%s\n", record.name, record.id, record.score, record.grade, record.salary, record.hp);
			id++;
		}
		close(fd);
	}
	//학생 정보 삽입
	else if(k == 1){
		printf("\n학번에 음수값 입력시 종료\n\n");
		printf("학번 이름 핸드폰번호 점수 장학금정보\n");
		while (scanf("%d %s %s %d %d", &record.id, record.name, record.hp, &record.score, &record.salary) == 5 && record.id > 0) {
			record.del = 1;
			if(record.score >= 95) strcpy(record.grade,ad);//{record.grade[0] = "A"; record.grade[1] = "+";}
                        else if(record.score >= 90) strcpy(record.grade,a);
                        else if(record.score >= 85) strcpy(record.grade,bd);
                        else if(record.score >= 80) strcpy(record.grade,b);
                        else if(record.score >= 75) strcpy(record.grade,cd);
                        else if(record.score >= 70) strcpy(record.grade,c_);
                        else if(record.score >= 65) strcpy(record.grade,dd);
                        else if(record.score >= 60) strcpy(record.grade,d);
                        else strcpy(record.grade,f);//record.grade[0] = "F";
			lseek(fd, (record.id - START_ID) * sizeof(record), SEEK_SET);
			write(fd, (char *) &record, sizeof(record) );
			}
		close(fd);
	}
	//학생 정보 보기
	else if(k == 2){
		ret = 0;
		do 
		{
			id = 1;
			cnt = 0;
			printf("\n\n검색할 학생의 학번 이름:");
			scanf("%s", na);
				while (cnt != 1 && id <= START_ID) {
					lseek(fd, (id - START_ID) * sizeof(record), SEEK_SET);
					ret = strcmp(record.name, na);
					if (ret == 0) cnt = 1;
					id = id + 1;
				}
				if (cnt == 1 && (record.del != 0) && (read(fd, (char *)&record, sizeof(record)) > 0) && (record.id != 0))
					printf("이름:%s\t 학번:%d\t 점수:%d\t 연락처:%s\t 등급:%s\n", record.name, record.id, record.score, record.hp, record.grade);
				else printf("레코드 없음\n");
			printf("계속하겠습니까?(Y/N)");
 
			scanf("%c", &c);
		}while (c == 89 || c == 121);
 
		close(fd);
	}
	//장학금 수정
	else if(k == 3){
		printf("\n\n수정할 학생의 학번 입력(-값 입력시 종료):");
		while (scanf("%d", &id) == 1) {
			lock.l_type = F_WRLCK;
			lock.l_whence = SEEK_SET;
			lock.l_start = (id-START_ID)*sizeof(record);
			lock.l_len = sizeof(record);
			if (fcntl(fd,F_SETLKW, &lock) == -1) { /* 쓰기 잠금 */
				perror(argv[1]);
				exit(3);
			}
			lseek(fd, (long) (id-START_ID)*sizeof(record), SEEK_SET);
			if ((read(fd, (char *) &record, sizeof(record)) > 0) && (record.id != 0))
				printf("이름:%s\t 학번:%d\t 핸드폰번호:%s\t 점수:%d\t 장학금:%d\n ", record.name, record.id, record.hp, record.score, record.salary);
			else printf("레코드 %d 없음\n", id);
			printf("수정금액: ");
			scanf("%d", &record.salary);
			lseek(fd, (long) -sizeof(record), SEEK_CUR);
 
			write(fd, (char *) &record, sizeof(record));
			lock.l_type = F_UNLCK;
 
			fcntl(fd, F_SETLK, &lock); /* 잠금 해제 */
			printf("\n수정할 학생의 학번 입력:");
		}
		close(fd);
		//exit(0);
	}
	//삭제
	else if(k == 4){
		do {
			printf("\n\n삭제할 학생의 학번 :");
			if (scanf("%d", &id) == 1) {
				lseek(fd, (id - START_ID) * sizeof(record), SEEK_SET);
				if ((record.del != 0) && (read(fd, (char *)&record, sizeof(record)) > 0) && (record.id != 0))
					record.del = 0;
				else printf("레코드 없음\n");
			}
			else printf("입력 오류");
			printf("계속하겠습니까?(Y/N)");
 
			scanf(" %c", &c);
		} while (c == 89 || c == 121);
 
		close(fd);
		//exit(0);
	}
	else printf("잘못된 입력\n");
	printf("다른 작업을 하시겠습니까?(Y/N) : ");
	scanf("%s",&s);
	if(s == 89 || s == 121) k = 99;
	else k = 4;
	}
	close(fd);
	exit(0);
	return 0;
}

student.h 소스 코드

#define MAX 24
#define START_ID 1201001
#define FINAL_ID 1801999
 
struct student {
	int del;
	int id;
	char name[MAX];
	char hp[MAX];
	char grade[3];
	int score;
	int salary;
};

리눅스도 거의 안만져봤는데
우분투 9월에 처음 만져보고 리눅스에서 C만드는것도 거의 처음이라..

애초에 C 못하는 편이라 가독성 부서져있는데 이해해주세요

질문은 컴파일 해보면 아실텐데
학번이랑 다 입력하고 0번이나 2번 눌러서 목록보기나 검색해보면 아무것도 안뜹니다 ㅎ
살려주세요

그리고 검색,목록보기 코드 짤 때 몰라서 처음부터 끝까지 검색하고 값 나오도록 하게 했는데
이렇게 말고 다르게 짤 수 있는 방법은 있을까요?

익명 사용자의 이미지

엉망진창인데요.

가독성이 문제가 아니라, 코드에서 전반적으로 엿보이는 C언어 구사 능력에 비해 고급 테크닉이 쓰이고 있는 점이 혼란스럽습니다.

fcntl으로 record lock은 왜 잡으신 건가요? 흐음;

뭐 여러 문제가 있을 수 있겠지만 눈에 띄는 거 하나만 지적해 드리겠습니다.

		while (id <= START_ID) {
			lseek(fd, (id - START_ID) * sizeof(record), SEEK_SET);

while문 안쪽에서, (id - START_ID)는 어떤 값을 가지게 될까요?

jachin의 이미지

이전 질문에서는 멀쩡한 코드가 제대로 작동하지 않는다고 질문하셔서 답글을 달았지만, 본인에게 문제해결능력이 없다는 것을 아셨으면 공부하셔서 해결하셔야 하지 않을까요? 정말 몰라서 처음하시는 분이 받으실 과제내용은 아닌 것 같습니다. 수업과정으로 과제를 받으신 것이라면 응당한 노력을 하셔야 합니다.

wkfdlek의 이미지

덕분에 얻어맞고 잘풀었습니다ㅎ

과제라서 올리기가 뭐하네요
시험기간이라 포기할까도 생각하다가 저거 베이스로 시험문제 나온다고해서 시간여유있음에도 못풀면 못잘거 같아서 풀었습니다