파일 입출력 -3

언어/C 2016. 3. 18. 00:45

텍스트와 바이너리 데이터의 집합체인 구조체 변수의 입출력

⇒ 구조체 변수를 하나의 바이너리 데이터로 인식하고 처리

ex)

fp=fopen("friend.bin", "wb");

printf("이름, 성별, 나이 순 입력: ");

scanf("%s %c %d", myfren1.name, &(myfren1.sex), &(myfren1.age));

fwrite((void *)&myfren1, sizeof(myfren1), 1, fp);

fclose(fp);


fp=fopen(~~~);

fread((void*)&myfren2, sizeof(myfren2), 1, fp);

printf("%s %c %d \n", myfren2.name, myfren2.sex, myfren2.age);

fclose(fp);


파일 위치 지시자 : 파일이 처음 개방되면 무조건 파일의 맨 앞부분 가리킴

1
2
3
#include <stdio.h>
 
int fseek(FILE * stream, long offset, int wherefrom);


파일 위치 지시자의 이동 : seek (stream으로 전달된 파일 위치 지시자를 wherefrom에서부터 offset 바이트만큼 이동)ㅁ

성공시 0, 실패시 0이 아닌 값 반환

 매개변수 wherefrom 이...

파일 위치 지시자는... 

SEEK_SET(0) 이라면

파일 맨 앞에서부터 이동을 시작 

SEEK_CUR(1) 이라면

현재 위치에서부터 이동을 시작

SEEK_END(2) 이라면

파일 맨 끝에서부터 이동을 시작

파일의 맨 끝은 마지막 데이터가 아니라 EOF를 의미

매개변수 offset에 양의 정수 전달 : 파일의 마지막을 향해서 파일 위치 지시자 이동

음의 정수 전달 : 파일의 시작 위치를 향해서 파일 위치 지시자 이동


현재 파일 위치 지시자의 위치 : ftell

1
2
3
#include <stdio.h>
 
long ftell(FILE * stream);


가장 앞 부분의 바이트 위치를 0으로 간주


'언어 > C' 카테고리의 다른 글

static 변수  (0) 2016.03.21
메모리 관리와 메모리의 동적 할당  (0) 2016.03.20
파일 입출력 -2  (0) 2016.03.13
파일 입출력 -1  (0) 2016.03.10
구조체 기초 (열거형 enum)  (0) 2016.03.10
Posted by 知彼知己百戰不殆
,

파일 입출력 -2

언어/C 2016. 3. 13. 23:53

파일의 개방 모드 (웬만하면 r,w,a 중에서 선택)

모드 

 스트림의 성격

일이 없을 경우 

 r

 읽기 가능

Error 

 w

 쓰기 가능

생성 

 a

 파일 끝에 덧붙여 쓰기 가능

 r+

 읽기/쓰기 가능

Error 

 w+

 읽기/쓰기 가능

생성 

 a+

 읽기/덧붙여 쓰기 가능

생성

1. 모드의 +는 읽기, 쓰기가 모두 가능한 스트림의 형성을 의미

2. 모드의 a는 쓰기(덧붙이기)가 가능한 스트림 형성


윈도우(\r\n), UNIX(\n), Mac(\r) 계열마다 파일 내 개행이 다르므로 형태 변환을 시켜줘야 한다.

형태 변환은 파일을 텍스트 모드(fopen사용시)로 개방하면 자동으로 됨.

C프로그램에서 \n을 파일에 저장하면 윈도우에서는 \r\n으로 변환되어 저장됨.


텍스트 모드의 파일 개방을 위해서는 fopen 함수의 두 번째 인자로 다음 중 하나 전달

rt, wt, at, r+t(rt+), w+t(wt+), a+t(at+)

바이너리 데이터를 저장하고 있는 파일의 경우 형태의 변환이 일어나면 안되므로 바이너리 모드로 파일 개방.

rb, wb, ab, r+b(rb+), w+b(wb+), a+b(ab+)

개방 모드에 아무것도 붙이지 않으면 디폴트 값은 텍스트 모드


feof함수 : 파일의 끝 확인할 때 사용

1
2
3
#include <stdio.h>
 
int feof(FILE * stream);


파일의 끝에 도달한 경우 0이 아닌 값 반환

한 파일에서 다른 파일로 복사를 할 때 완전하게 파일 끝까지 복사가 다 됐는지 확인할 때 사용

fgetc나 fgets함수가 EOF를 반환했다고 해서 무조건 파일의 끝에 도달했다고 판단할 수 없다. 오류가 발생하는 경우에도 EOF가 반환


바이너리 데이터의 입출력 fread, fwrite

1
2
3
#include <stdio.h>
 
size_t fread(void * buffer, size_t size, size_t count, FILE * stream);


 성공시 전달인자 count, 실패 또는 파일의 끝 도달 시 count보다 작은 값 반환


1
2
3
#include <stdio.h>
 
size_t fwrite(void * buffer, size_t size, size_t count, FILE * stream);


성공시 전달인자 count, 실패 시 count보다 작은 값 반환

만약 fwrite((void*)but, sizeof(int), 12, fp) 이렇게 함수가 정의돼 있다면 한 번 호출할 때마다 12만큼씩 데이터를 써라..라는 뜻.. 최소 12만큼 쓰는게 아니라 그냥 무조건 12만큼 써라 라는 뜻


서식에 따른 데이터 입출력 : fprintf, fscanf

printf와 scanf 함수와 비슷, 입출력 대상이 콘솔이 아닌 파일

ex) char name[10]="홍길동";

char sex='M';

int age = 24;

fprintf(fp, "%s %c %d", name, sex, age); fp는 파일 구조체 포인터


fscanf : 첫 번째 인자로 전달된 포인터가 지칭하는 파일로부터 데이터를 읽어들임   

ex) char name[10];

char sex ;

int age;

fscanf(fp, "%s %c %d", name, &sex, &age);

'언어 > C' 카테고리의 다른 글

메모리 관리와 메모리의 동적 할당  (0) 2016.03.20
파일 입출력 -3  (0) 2016.03.18
파일 입출력 -1  (0) 2016.03.10
구조체 기초 (열거형 enum)  (0) 2016.03.10
구조체 기초 (union, struct의 차이)  (0) 2016.03.07
Posted by 知彼知己百戰不殆
,

파일 입출력 -1

언어/C 2016. 3. 10. 11:18

스트림(stream) : 데이터 이동의 경로가 되는 다리, program과 파일 사이에 스트림을 형성해야 데이터를 주고 받을 수 있다.

파일 : 운영체제에 의해서 그 구조가 결정되고 관리되는 대상, 파일 뿐만 아니라 스트림의 형성도 운영체제의 몫임을 기억해야 한다.


fopen 함수 호출을 통한 파일과의 스트림 형성과 FILE 구조체

1
2
#include <stdio.h>
FILE * fopen(const char * filename, const char * mode);


fopen 함수의 반환형은 FILE인데 구조체의 포인터이다. 파일을 가리키기 위한 용도로 사용됨.

이 포인터를 이용해서 파일에 데이터를 저장하거나 파일에 저장된 데이터를 읽게 된다.


fputc('A',fp); fp(파일포인터)가 가리키는 곳에 문자 'A' 저장 


fclose : 스트림의 소멸(해제)을 요청하는 함수

1
2
3
#include <stdio.h>
 
int fclose(FILE * stream);


fclose 함수가 호출이 되면 데이터는 안정적으로 저장이 됨.

개방되었던 파일을 닫아주어야 하는 이유 : 운영체제가 할당한 자원의 반환,  버퍼링 되었던 데이터의 출력


fflush : 스트림을 종료하지 않고 버퍼만 비우고 싶을 때

1
2
3
#include <stdio.h>
 
int fflush(FILE * stream);


출력 버퍼를 비움 : 출력 버퍼에 저장된 데이터를 목적지로 전송한다는 의미

입력 버퍼를 비움 : 입력 버퍼에 저장된 데이터를 소멸 시킨다는 의미

fflush 함수는 출력 버퍼를 비우는 함수, 입력 버퍼를 대상으로 호출할 수 없음


저장한 파일을 읽어들일 때에는 fopen함수의 mode부분을 "rt"로 바꿔주고 fgetc로 읽어들이면 됨


'언어 > C' 카테고리의 다른 글

파일 입출력 -3  (0) 2016.03.18
파일 입출력 -2  (0) 2016.03.13
구조체 기초 (열거형 enum)  (0) 2016.03.10
구조체 기초 (union, struct의 차이)  (0) 2016.03.07
escape sequence  (0) 2016.02.26
Posted by 知彼知己百戰不殆
,

열거형(Enumerated Type)

저장이 가능한 값 자체를 정수의 형태로 결정한다. 사용형태는 구조체랑 비슷하다.


사용 형태 : 

enum (name)

{

~~~~

};


열거형 상수의 값이 결정되는 방식

enum color { A, B, C, D };

A=1, B=2, C=3 ... 0에서부터 시작하여 1씩 증가하는 형태

enum color { A=1, B, C=4,D};

B=2, D=5... 선언되어 있지 않은 값은 앞서 선언된 상수보다 1이 증가된 값이 할당


열거형의 유용함은 둘 이상의 연관이 있는 이름을 상수로 선언, 자료형의 이름을 생략한 형태로 열거형을 정의할 수도 있다.


'언어 > C' 카테고리의 다른 글

파일 입출력 -2  (0) 2016.03.13
파일 입출력 -1  (0) 2016.03.10
구조체 기초 (union, struct의 차이)  (0) 2016.03.07
escape sequence  (0) 2016.02.26
counting program  (0) 2016.02.18
Posted by 知彼知己百戰不殆
,

공용체(Union Type)의 정의와 의미

<구조체와 Union address, value 확인>

#include <stdio.h>
#include <stdint.h>

typedef struct {
    int a;
    int b;
    char c;
} number;

typedef union {
    int a;
    int b;
    char c;
    char d;
} utemp;

int main()
{
    number num1;
    utemp utem;
    utem.a=4;
    utem.b=6;
    utem.c='a';
    utem.d='b';
    printf("\n[STRUCT]\n"); 
    printf("size=%d\n",sizeof(num1));
    printf("size=%p\n",&num1.a);
    printf("size=%p\n",&num1.b);
    printf("size=%p\n",&num1.c);
    printf("\n[UNION]\n"); 
    printf("size=%d\n",sizeof(utem));
    printf("size=%p\n",&utem.a);
    printf("size=%p\n",&utem.b);
    printf("size=%p\n",&utem.c);
    printf("size=%p\n\n",&utem.d);
}


<struct 안의 union 공용체 address, value 확인>

#include <stdio.h>
#include <stdint.h>

typedef struct {
        int a;
        int b;
        char c;
union {
        int d;
        int e;
        char f;
};
        int g;

} number;

int main()
{
        number num1;
        num1.a = 1;
        num1.b = 2;
        num1.d = 4;
        printf("\n[STRUCT]\n");
        printf("size=%d\n\n",sizeof(num1));
        printf("b=%p\n",&num1.b);
        printf("c=%p\n",&num1.c);
        printf("d=%p\n",&num1.d);
        printf("e=%p\n",&num1.e);
        printf("f=%p\n",&num1.f);
        printf("g=%p\n\n",&num1.g);

}

struct 안에 union 선언을 한 경우 union 구조체 자체가 한 개의 메모리를 할당 받아서 사용함을 알 수 있다.


정의방식의 차이 :

struct선언 or union 선언

메모리 공간 할당되는 방식과 접근 결과 차이

1. 

sizeof로 구조체와 공용체(union) 찍어보면 각각 12, 4 출력

2. 

구조체 변수 - 구성 멤버는 각각 메모리 할당, 하지만 그 구조체 내부의 변수 타입중 가장 큰 놈의 사이즈로 모두 할당해버림.

공용체 변수 - 각각 할당(X), 크기가 가장 큰 멤버의 변수 타입만 하나 할당되어 이를 공유

공용체의 멤버에 값을 한 번 대입하고, 두 번 대입하면 두 번째 값이 모든 값을 덮어씀


typedef union

{

int n1;

int n2;

double n3;

};

위의 코드처럼 선언하면 밑에 그림처럼 생성이 된다.


'언어 > C' 카테고리의 다른 글

파일 입출력 -1  (0) 2016.03.10
구조체 기초 (열거형 enum)  (0) 2016.03.10
escape sequence  (0) 2016.02.26
counting program  (0) 2016.02.18
Symbolic Constants  (0) 2016.02.16
Posted by 知彼知己百戰不殆
,

escape sequence

언어/C 2016. 2. 26. 10:59



'언어 > C' 카테고리의 다른 글

구조체 기초 (열거형 enum)  (0) 2016.03.10
구조체 기초 (union, struct의 차이)  (0) 2016.03.07
counting program  (0) 2016.02.18
Symbolic Constants  (0) 2016.02.16
구조체(structure) - 중급  (0) 2016.01.09
Posted by 知彼知己百戰不殆
,

counting program

언어/C 2016. 2. 18. 17:39

Counting Program


Source Code

#include <stdio.h>

int main() {

double nc;

for(nc=0;getchar()!=EOF;++nc)

;

printf("%.0f\n",nc);

}


if the input contains no characters, the while or for test fails on the very first call to get char, and the program produces zero. while and for is that they test at the top of the loop, before proceeding with the body. If there nothing to do, nothing is done. Even if that means never going through the loop body.


Source : The C Programming language

'언어 > C' 카테고리의 다른 글

구조체 기초 (union, struct의 차이)  (0) 2016.03.07
escape sequence  (0) 2016.02.26
Symbolic Constants  (0) 2016.02.16
구조체(structure) - 중급  (0) 2016.01.09
구조체(structure) - 기초  (0) 2016.01.08
Posted by 知彼知己百戰不殆
,

Symbolic Constants

언어/C 2016. 2. 16. 17:10

COMPOSITION

#define   name   replacement text


name : same form as a variable name. a sequence of letters and digits that begins with a letter. conventionally written in upper case(capital letter).


no semicolon at the end of a #define line


advantage : easy to change in a systematic way


source : The C programming language

Posted by 知彼知己百戰不殆
,


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct person
{
        char name[20];
        int age;
};
 
int main() {
        struct person blair;
        strcpy(blair.name, "blair");
        printf("구조체 blair의 이름:%s\n",blair.name);
}
 
cs

위 코드와

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct person
{
        char name[20];
        int age;
};
 
int main() {
        struct person blair={strcpy(blair.name, "blair")};
        printf("구조체 blair의 이름:%s\n",blair.name);
}
 
cs

차이점?


첫 번째 코드 : 구조체 변수를 선언해놓고 나중에 strcpy를 써서 문자열을 옮김

두 번째 코드 : 구조체 변수의 초기화

 => 구조체 배열의 초기화 과정에서는 strcpy 함수를 호출하지 않아도 됨


*참고*

구조체에 키보드로 부터 입력받을 때는 scanf같은 거 사용하면 됨








Posted by 知彼知己百戰不殆
,

구조체 : 하나 이상의 변수(포인터 변수와 배열 포함)를 묶어서 새로운 자료형을 정의하는 도구, 사용자가 새로운 자료형 정의 가능


구조체 변수의 선언

struct type_name val_name

구조체 변수 선언시 위처럼 struct선언을 추가해야 하며, 이어서 구조체 이름, 구조체 변수 이름을 선언해야 한다.


구조체 내부에 있는 변수 접근시

구조체 변수의 이름(val_name).구조체 멤버 이름



구조체 선언 방법

struct point      // 구조체 정의와 변수의 선언, 여기서 point는 int나 double처럼 자료형의 이름이 된다

{

   int xpos;

   int ypos;

} pos1, pos2, pos3;    이런 식으로 구조체를 정의함과 동시에 구조체 변수를 선언할 수도 있고


struct point     // 구조체의 정의, 여기서 point는 int나 double처럼 자료형의 이름이 된다

{

    int xpos;

    int ypos;

};

struct point pos1, pos2, pos3;   // 구조체 변수의 선언



구조체 배열

ex) struct point arr[3]; 이런 식으로 구조체 배열 선언

구조체 배열을 선언과 동시에 초기화 시 배열의 길이만큼 중괄호를 이용해서 초기화를 진행

ex) struct person arr[3]={

{"blair","290490"},{"Alice","39848"},{"Ryan","57839"} };



구조체 변수와 포인터

ex) struct point pos={11,12};

struct point * pptr = &pos; // 포인터 변수 pptr이 구조체 변수 pos를 가리킨다.

(*pptr).xpos = 10;  // pptr이 가리키는 구조체 변수의 멤버 xpos에 10 저장

(*pptr).ypos = 20;

(*pptr).xpos = 10 이 문장은 pptr -> xpos = 10; 이 문장과 동일하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
struct point {
    int xpos;
    int ypos;
};
 
struct circle {
    double radius;
    struct point * center;
};
 
int main() {
    struct point cen = {2,7};
    double rad = 5.5;
 
    struct circle ring = {rad, &cen};
    printf("Center Circle is [%d, %d]\n", (ring.center)->xpos, (ring.center)->ypos);
}
cs

위 코드에서 보면 circle 구조체 안에 구조체 포인터 center을 선언해놓고, 나중에 point형 구조체를 초기화 하면서 구조체의 주소값을 ring 구조체에 넘겨주었다. 즉, ring.center가 가리키는 값은 point형 구조체 cen이다.

*추가*  TYPE형 구조체 변수의 멤버로 TYPE형 포인터 변수를 둘 수 있다.


구조체 변수의 조소 값과 첫 번째 멤버의 주소 값

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
struct point
{
        int xpos;
        int ypos;
};
 
struct person {
        int name[1];
        int phoneNum[1];
        int age;
};
 
int main() {
        struct point pos={10,20};
        struct person man={1,1,21};
 
        printf("%p\n%p\n%p\n%p\n",&man, &man.name,&man.phoneNum,&man.age);
}
 
cs

 코드 결과값



그냥 우리가 익히 아는 주소값 개념 그대로 적용된다. 만약 int name[1]대신에 char name[20]이면 주소값이 20차이가 남



typedef 선언

typedef : 기존에 존재하는 자료형의 이름에 새 이름을 부여하는 것을 목적으로 하는 선언

ex) typedef unsigned int * PTR_UINT; // unsigned int형 pointer을 PTR_UINT로 선언


구조체 배열의 초기화

struct person arr[2]={ 

{"김개똥","1234-1234",24},{"홍길동","1234-4234",28}

};


구조체 포인터

struct point pos = {11, 12};

struct point *pptr = &pos;

(*pptr).xpos = 10;  or  pptr->xpos=10; (*연산과 . 연산을 -> 연산으로 대신)


typedef 선언

기존에 존재하는 자료형의 이름에 새 이름을 부여하는 것

ex) typedef int INT;     //int의 또 다른 이름 INT를 부여

typedef struct (point)<< 구조체 변수 이름인 point는 생략가능

{

int xpos;

int ypos;

} Point;

그리고 이렇게 되면 구조체 변수 이름인 point는 거의 쓰이지 않아서 생략이 가능하다. 다만 생략할 경우 struct point man; 이런 식으로 선언 못함


구조체도 call by reference가 가능하다.

typedef struct point

{

~~~~

} Point;

void OrgSymTrans(Point * ptr)

{

~~~~

}

int main() {

Point pos={7,-5};

OrgSymTrans(&pos);

}

Posted by 知彼知己百戰不殆
,