• 입력
char str3[20];
fgets(str1, 20, stdin);
scanf("%[^\n]s", &str3);
공백 구분해서 입력받는 방법 2가지
fgets(입력받을 문자열, 받을 문자열 길이, stdin);
scanf("[^\n]%s", &입력받을 char[길이]); <- 정규식 사용해서 엔터 아닌거까지 다 입력받음
scanf("%[^ ]s", &str3); <- 스페이스 아닌거 다 입력받음
• 배열 입출력
int* 로 받지만 int arr[10] 형태로 선언한 배열도 입출력 가능하다
int score[10];
void scoreEnter(int* score) {
for (int i = 0; i < 10; i++)
{
scanf("%d", &score[i]);
}
}
void scorePrint(int* score) {
for (int i = 0; i < 10 ; i++)
{
printf("%d ", score[i]);
}
printf("\n");
}
• malloc
선언 후 메모리 널 체크 한 다음 사용, 사용후 반드시 메모리 해제
int main(void) {
int *arr = malloc(sizeof(int) * 20);
if(arr == NULL){
printf("메모리 할당 실패");
return -1;
}
for (int i = 0; i <20 ; i++) {
arr[i] = i;
printf("%d\n", arr[i]);
}
free(arr);
}
• 연속된 입력에서 개행문자('\n')을 제거하는 예제
names[i][strlen(names[i])-1] = '\0';은
strlen이 반환하는 문자열의 마지막 문자를 널 문자로 바꿔서 다시 fgets를 할때 입력을 제대로 받을수 있게 만들어준다
int main(void) {
char names[2][10];
for (int i = 0; i < 2; i++)
{
fgets(names[i], 10, stdin);
names[i][strlen(names[i])-1] = '\0'; //개행 문자 제거하기
printf("%d\n",strlen(names[i]));
for (int j = 0; j < strlen(names[i]); j++)
{
printf("%c ", names[i][j]);
}
printf("\n");
}
}
• 연결리스트 요소를 출력하고 메모리를 해제하려면?
포인터 노드 변수를 만들어서 그 변수에 현재 노드의 주소를 넣어주고
다음 노드를 지정한 다음
현재 노드 주소를 들고 있는 포인터 노드 변수를 해제해주면 현재 노드가 출력된 후 해제된다
temp = HEAD;
while (temp != NULL)
{
struct link* currentNode = temp;
printf("id : %d, 이름 : %s\n", temp->id, temp->bookname);
temp = temp->next;
free(currentNode);
}
이중 연결리스트 예제
insert, delete 메서드의 경우 이중 포인터를 사용해서 데이터를 넘겨주었는데
단일 포인터를 사용해서 head와 tail을 넘겨주는 경우에는 원본의 헤드,테일을 복사해서 사용하기에
넘겨준 값을 변경해도 값의 변화가 일어나지 않는다
원본의 값 까지 변경하고 싶으면 이중 포인터를 사용해서 head와 tail의 주소값을 넘겨주어 변경시켜야 한다
#마이리스트
#pragma once
struct link {
int id;
char bookname[30];
struct link* next;
};
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // strlen 함수 사용을 위해 추가
#include "myList.h"
void printList(struct link* HEAD) {
struct link* temp = HEAD;
while (temp != NULL) {
printf("id : %d, 이름 : %s\n", temp->id, temp->bookname);
temp = temp->next;
}
}
void search(char* name, struct link* HEAD) {
struct link* temp = HEAD;
while (temp != NULL) {
if (strcmp(temp->bookname, name) == 0) {
printf("찾은 책 id : %d\n", temp->id);
return;
}
temp = temp->next;
}
printf("해당 책 없음\n");
}
void deleteNode(char* name, struct link** HEAD, struct link** TAIL) {
struct link* temp = *HEAD;
struct link* prev = NULL;
while (temp != NULL) {
if (strcmp(temp->bookname, name) == 0) {
printf("id %d인 노드 삭제\n", temp->id);
if (temp == *HEAD) {
*HEAD = temp->next;
if (temp == *TAIL) *TAIL = NULL;
}
else if (temp == *TAIL) {
*TAIL = prev;
if (prev != NULL) {
prev->next = NULL;
}
}
else {
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
}
free(temp);
return;
}
prev = temp;
temp = temp->next;
}
printf("해당 책 없음\n");
}
void insertNode(int id, struct link** HEAD, struct link** TAIL) {
struct link* temp = *HEAD;
struct link* prev = NULL;
while (temp != NULL) {
if (temp->id == id) {
struct link* new = (struct link*)malloc(sizeof(struct link));
new->prev = NULL;
new->next = NULL;
if (new == NULL) {
printf("메모리 할당 실패\n");
return;
}
printf("id : ");
scanf("%d", &new->id);
getchar();
printf("이름 : ");
fgets(new->bookname, 20, stdin);
new->bookname[strlen(new->bookname) - 1] = '\0';
if (temp == *HEAD) { //머리일때
(*HEAD)->prev = new;
new->next = (*HEAD);
*HEAD = new;
return;
}
else if (temp == *TAIL) { //꼬리일때
(*TAIL)->next = new;
new->prev = (*TAIL);
*TAIL = new;
return;
}
if (prev != NULL) { // 중간일때
new->next = prev->next;
prev->next = new;
new->prev = prev;
return;
}
new->next = temp;
return;
}
prev = temp;
temp = temp->next;
}
}
void Enter(struct link** HEAD, struct link** TAIL) {
struct link* temp = (struct link*)malloc(sizeof(struct link));
if (temp == NULL) {
printf("메모리 할당 실패\n");
exit(1);
}
printf("id : ");
scanf("%d", &temp->id); // 멤버가 int형이니 scanf때 &로 참조하기
getchar();
printf("이름 : ");
fgets(temp->bookname, 20, stdin);
temp->bookname[strlen(temp->bookname) - 1] = '\0';
temp->next = NULL;
temp->prev = NULL;
if (*HEAD == NULL) {
*HEAD = temp;
*TAIL = temp;
}
else {
(*TAIL)->next = temp;
temp->prev = *TAIL;
*TAIL = temp;
}
}
void load(struct link** HEAD, struct link** TAIL) {
FILE* f = fopen("list.txt", "r");
printf("filename : %s\n", __FILE__);
printf("function name : %s\n", __FUNCTION__);
if (f == NULL) {
fprintf(stderr, "파일 열리지 않음\n");
exit(1);
}
int id;
char bookname[80];
while (fscanf(f, "%d %s", &id, bookname) != EOF) {
struct link* newNode = (struct link*)malloc(sizeof(struct link));
if (newNode == NULL) {
fprintf(stderr, "메모리 할당 실패\n");
exit(1);
}
newNode->id = id;
strcpy(newNode->bookname, bookname, sizeof(newNode->bookname) - 1);
newNode->bookname[sizeof(newNode->bookname) - 1] = '\0';
newNode->next = NULL;
newNode->prev = NULL;
if (*HEAD == NULL) {
*HEAD = newNode;
*TAIL = newNode;
}
else {
(*TAIL)->next = newNode;
newNode->prev = *TAIL;
*TAIL = newNode;
}
}
fclose(f);
}
void save(struct link** HEAD) {
FILE* f = fopen("list.txt", "w");
if (f == NULL)
{
fprintf(stderr, "파일 열리지 않음");
exit(1);
}
struct link* temp = *HEAD;
while (temp != NULL) {
fprintf(f, "%d %s\n", temp->id, temp->bookname);
printf("%d %s\n", temp->id, temp->bookname);
temp = temp->next;
}
fclose(f);
}
int main() {
struct link* HEAD = NULL;
struct link* TAIL = NULL;
load(&HEAD, &TAIL);
while (1) {
printf("1 : 입력\n");
printf("2 : 출력\n");
printf("3 : 검색\n");
printf("4 : 삭제\n");
printf("5 : 삽입\n");
printf("9 : 종료\n");
printf("선택 --> ");
int num = 0;
scanf("%d", &num);
switch (num) {
case 1: // 입력
Enter(&HEAD, &TAIL);
break;
case 2: // 출력
printList(HEAD);
break;
case 3: // 검색
{
getchar();
char name[20];
printf("검색할 책 이름을 입력하세요: ");
fgets(name, 20, stdin);
name[strlen(name) - 1] = '\0';
search(name, HEAD);
break;
}
case 4: // 삭제
{
getchar();
char name[20];
printf("삭제할 책 이름을 입력하세요: ");
fgets(name, 20, stdin);
name[strlen(name) - 1] = '\0';
deleteNode(name, &HEAD, &TAIL);
break;
}
case 5: // 삽입
{
int tmp = 0;
printf("삽입할 위치의 id를 입력하세요: ");
scanf("%d", &tmp);
insertNode(tmp, &HEAD, &TAIL);
break;
}
case 9: // 종료
printf("종료합니다\n");;
save(&HEAD);
{
// 메모리 해제
struct link* temp = HEAD;
struct link* btemp;
while (temp != NULL) {
btemp = temp->next;
free(temp);
temp = btemp;
}
}
return 0;
default:
printf("잘못된 선택입니다. 다시 선택해주세요.\n");
break;
}
}
}
• 파일 입출력
fgets/fputs - 파일에서 줄 단위로 텍스트를 읽어올때 사용하기 좋음
fprintf/fscanf - 파일에서 특정 타입의 데이터를 가져올 때 사용하기 좋음
fread/fwrite - 바이트 단위로 입출력 할때 사용
-쓰기
File* fp = fopen(파일이름,"a");
형태로 사용
이름 다음에 "r" "w" "a" 등 필요한 것 마다 다른 옵션 사용가능
fputs(입력할 문자열, 파일이름);
형태로 파일에 사용자가 입력한 문자열 기록 가능
FILE* fp = fopen("a.txt", "a");
if (fp == NULL)
{
printf("파일 열리지 않음");
return 1;
}
char st[50];
fgets(st, sizeof(st), stdin);
fputs(st, fp);
fclose(fp);
-읽기
FILE* fp = fopen("a.txt", "r");
"r"로 읽기 모드로 읽는걸 지정해준다
int ch;로 문자열을 읽어올 int 변수를 지정하고
반복문을 돌면서 eof를 만날 때 까지 fgetc(파일) 형태로 문자를 가져오고
putchar(ch);로 가져온 문자를 출력한다
FILE* fp = fopen("a.txt", "r");
if (fp == NULL)
{
printf("파일 열리지 않음");
return 1;
}
int ch;
while (1)
{
ch = fgetc(fp);
if (ch == EOF) {
printf("\n파일 끝\n");
break;
}
putchar(ch); //화면에 입력받은 글자 출력
}
fclose(fp);
return 0;
- fprintf/fscanf 예제
파일에 쓰는 기능이 fprintf(파일, 인자 자료형, 인자들)
파일의 내용을 읽어오는 기능이 fscanf(파일, 인자 자료형, 인자들)
typedef struct type {
int num;
double dnum;
char string[80];
} TYPE;
int main()
{
TYPE arr = { 10, 1.2345, "hello" }, arr1;
FILE* fp = fopen("a.txt", "w");
if (fp == NULL)
{
fprintf(stderr, "파일 열리지 않음\n");
return 1;
}
//구조체 내용을 파일에 쓰기
fprintf(fp, "%d %lf %s\n", arr.num, arr.dnum, arr.string);
fclose(fp);
fp = fopen("a.txt", "r");
if (fp == NULL)
{
fprintf(stderr, "파일 열리지 않음\n");
return 1;
}
//파일에서 구조체 내용을 읽어와서 출력하기
fscanf(fp, "%d %lf %s", &arr1.num, &arr1.dnum, arr1.string);
printf("%d %lf %s\n", arr1.num, arr1.dnum, arr1.string);
fclose(fp);
return 0;
}
파일 사용했으면 꼭 fclose(파일이름); 으로 닫아주자!
'대외활동 > 시스템프로그래밍' 카테고리의 다른 글
시험대비 qt c++ 복습 (0) | 2024.08.25 |
---|---|
시험대비 c++ 복습 (0) | 2024.08.25 |
라이브러리 (0) | 2024.08.22 |
0822 gdb, core, valgrind (0) | 2024.08.22 |
보이드 포인터, 함수 포인터 복습 (0) | 2024.08.21 |