'Language/C'에 해당되는 글 66건

  1. 2011.12.01 포인터 배열
  2. 2011.11.18 char *로 할당된 스트링값
  3. 2011.11.18 fopen, open 차이
  4. 2011.11.14 파일 퍼미션
  5. 2011.11.09 bsearch / 이진탐색
  6. 2011.11.08 stat
  7. 2011.11.08 배열 크기 구하기
  8. 2011.11.07 exec 함수군
  9. 2011.11.04 현재 날짜와 시간 출력
  10. 2011.11.04 gettimeofday

포인터 배열

Language/C 2011. 12. 1. 20:46

포인터 배열이란 여러 개의 포인터 변수를 배열로 사용하는 것이다


포인터 배열은 문자형 포인터 배열을 사용할 때 유용하게 사용된다.


             char na[4][10] = {"Korea""Brazil""Germany""China"};


        char *ct[] = {"Korea""Brazil""Germany""China"};


 여러 개의 문자열을 문자형 배열에 저장할 때는 2차원 배열을 사용해야 하며, 2차원 배열의 두 번째 첨자의 크기는 저장할 


문자열의 길이를 감안하며 충분한 크기로 정해 주어야 한다2차원 배열에 문자열을 저장할 경우 기억 공간의 낭비가 생기지만 


포인터 배열을 이용할 경우에는 필요한 공간만을 사용하게 된다포인터 배열 ct의 각 배열 요소에는 각 문자열이 시작되는 주소가 


저장된다.


 int main(void

{

        char na[4][10] = {"Korea""Brazil""Germany""China"};

        char *ct[] = {"Korea""Brazil""Germany""China"};

 

        printf("na[2]: %s\n", na[2]);

        printf("na[2][3]: %c\n", na[2][3]);

        printf("ct[2]: %s\n", ct[2]);

        printf("ct[2][3]: %c\n", ct[2][3]);

        return 0;

}

'Language > C' 카테고리의 다른 글

void형 포인터  (0) 2011.12.02
이중 포인터의 필요성  (0) 2011.12.02
char *로 할당된 스트링값  (0) 2011.11.18
fopen, open 차이  (0) 2011.11.18
파일 퍼미션  (0) 2011.11.14
:

char *로 할당된 스트링값

Language/C 2011. 11. 18. 20:23

char *로 할당된 스트링값을 변경하는 방법에 대해서

neon20의 아바타

아래와 같은 형태로 이미 배정된 스트링값을 변경하는건 
불가능 한가요? 스트링값을 변경하기 위해선 배열만 사용해야 
하는건가요? 다른 방법이 있다면 알려주세요.

#include"stdio.h"

void main()
{
	char *a;
	a = "girl";
	*(a+0) = 'o';	
}

익명 사용자의 아바타

모든 문자열 상수(string literal)는 변경 불가능합니다.

모든 문자열 상수(string literal)는 변경 불가능합니다.

char *a;
a = "girl";
*(a+0) = 'o';    

"girl"은 문자열 상수이며 변경 불가능합니다.

char a[] = "girl";
a[0] = 'o';

a는 char형 배열이므로 변경 가능합니다.

정태영의 아바타

구버젼의 gcc 의 경우엔... 옵션으로 가능하게 할 수도 있었지만..

구버젼의 gcc 의 경우엔... 옵션으로 가능하게 할 수도 있었지만... 이젠 그 옵션이 아예 없어졌나보군요 ;)

mac gcc wrote:
-fwritable-strings
Store string constants in the writable data segment and don't uniquize them. This is for
compatibility with old programs which assume they can write into string constants.

Writing into string constants is a very bad idea; ``constants'' should be constant.

This option is deprecated.

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~ 나 한줄기 바람처럼..

hanzo69의 아바타

옛날 DOS라면 가능합니다만..

C언어 문법상으로 불가능한건 아닙니다. 예전 도스라면 가능했던 일이죠. 
문제는 그 문자열 상수가 어디에 있냐죠.

실행파일이 매번 실행될 때 실행파일 전체를 메모리에 별도로 복사한다면 가능한 일이지만, 리눅스나 윈도우 둘 다 한번만 메모리에 로딩하고 그 다음엔 이미 로딩한 실행파일 메모리를 공유해서 사용합니다.
문자열 상수는 이 공유되는 메모리에 속해있으며, 이 이미지 영역은 read-only 속성을 가지게 됩니다.
대신 전역변수는 읽기-쓰기 가능한 메모리를 할당해 배치시키죠. 
char a[] = "girl"; 
위와 같이 초기값이 있는 전역 변수는 실행시에 그러한 읽기-쓰기 가능한 메모리 영역으로 이미지 영역의 초기값을 복사하는 방식이구요.
char *a = "girl";
이런 경우엔 a가 읽기만 가능한 이미지 영역을 직접 가리키므로 쓰기를 하게 되면 세그-폴트가 발생하게 됩니다.

글쎄.. 윈도우라면 문자열 영역에 VirtualProtect()를 사용해서 PAGE_WRITECOPY 속성을 지정하면 쓰기 시도를 할 때 별도의 물리적 메모리에 자동적으로 복사하게 만들어 쓸 수 있긴 한데.. 
그러느니 차라리 직접 배열을 잡아 복사한 후 쓰는게 편하죠.

님ㅎ 즐~

neon20의 아바타

음..c의 포인터 스트링은 변경 불가능하군요..ㅜㅜ 너무 감사합니다

음..c의 포인터 스트링은 변경 불가능하군요..ㅜㅜ 
너무 감사합니다

익명 사용자의 아바타

[quote]C언어 문법상으로 불가능한건 아닙니다. 예전 도스라면 가능했

Quote:
C언어 문법상으로 불가능한건 아닙니다. 예전 도스라면 가능했던 일이죠.

문자열 상수를 수정하는 행동은 정의되지 않은 동작을 일으킵니다. 문법만 따지자면 불가능한 게 맞고, 예전 도스시절의 C(아마도 Turbo C인거 같은데)가 특별한 경우일 뿐입니다.

이와 관련하여 한가지 더 고려할 사항이 있는데

char *a = "str";
char *b = "str";

같은 내용을 가지는 문자열 상수는 하나만 만들어질 수도 있습니다(단, 항상 그래야 되는 것은 아닙니다.). 어차피 문자열 상수는 수정이 불가능하므로, 같은 내용이라면 하나만 만드는 것이 메모리 공간을 적게 차지합니다. 문자열 상수를 변경할 수 있다 해도, a가 가르키는 문자열 상수를 고치면 b가 가르치는 문자열 상수의 내용도 바뀔 수 있습니다.

Quote:
대신 전역변수는 읽기-쓰기 가능한 메모리를 할당해 배치시키죠.

전역변수와는 전혀 상관이 없습니다. 전역변수는 보통 file scope를 가지는 변수를 뜻하는 거라 알고 있습니다만... a가 전역변수이던 아니던, "str"은 수정 불가능합니다. 이것은 a가 가르키는 "str"이 문자열 상수이기 때문입니다.

char a[] = "str";

이 경우에는 a가 배열로 생성이 되고, "str"이란 내용으로 초기화됩니다. a는 char형 배열이므로 그 안의 내용을 변경할 수 있는 것이 당연합니다.

hanzo69의 아바타

c언어에 문자열형이 있던가요?

c언어에 문자열형이 있던가요?

c언어에선 문자열형이란 없을텐데요. 오직 포인터형, 정수형, 실수형 세가지뿐이죠. 정수형은 크기별로 몇가지가 있긴 있죠.
"abcd"는 문자열형이 아니고 메모리 공간일 뿐이며, 평가형은 (const char *)형입니다. 이걸 건드리든 말던 그건 프로그래머 자유죠.

"abcd"[0] = 0; 
이 코드는 "abcd" 자체가 상수가 아니라 (const char *) 형이 가리키는 데이터이므로 문법적으로 오류가 있을 뿐입니다.
((char *)"abcd")[0] = 0; 
char *p = "abcd";
p[0] = 0;
은 실제론 먼저의 코드와 같은 일을 하지만 문법적으론 아무 문제가 없는 코드죠. 단지 실행시에 오류가 날 뿐이죠.
정의되지 않은 동작이 아니고 a라는 문자의 위치에 0을 쓰려 시도를 합니다. 그리고 그 위치가 read-only라면 예외가 발생할 뿐이죠. 만약 롬과 램이 주소공간에 물린 아케이드 보드라면... 뭐 쓰기 시도가 무시되겠죠.

그리고 c언어 문법상으론 const 형은 자료형만 같다면 non-const 형에 대입할땐 자동 변환이 가능하도록 되어 있습니다.
char *p = (char *)"abcd"; // const char * 형을 char *형으로 변환
int i = (int)1; // const int형을 int형으로 변환
이렇게 명시적으로 변환하며 코딩하는 사람은 없죠. 
그리고 일단 변환된 이상은 건드리던 말던 시스템이 받아주는 한계 내에선 c의 문법 내에선 자유랍니다. 실행시 오류가 나면 나는거죠.

세상의 모든 시스템이 "abcd"를 건드려선 안되는건 아닙니다. 건드려도 무방한 시스템에선 얼마든지 건드려도 된답니다.
오히려 리눅스가 특별한 경우라면 특별한 경우겠죠. 원래 읽기 쓰기가 가능한 메모리를 읽기만 가능하게 만들었으니까요.
윈도우에선 "abcd" 영역을 copy on write 속성을 지정하면 쓰기가 가능하니 뭐... 좀 다르다 해야 할라나?

그리고 정적 변수와 전역변수의 의미에 대한 차이는 사실 c언어에선 무의미하지 않던가요?
어차피 함수 밖에서 변수를 선언하면 static 키워드를 따로 붙이지 않는 한 모두 전역변수랍니다.
그리고 static를 붙여도 외부에서 포인터를 얻는다면 얼마든지 접근이 가능하죠.

그리고 전역변수던 상수든지간에 c언어 문법상으론 모든 상수를 얼마든지 수정할 수 있답니다. 포인터를 얻어 쓰기를 하면 그만이니까요. 단 운영체제가 그 상수가 기억된 메모리를 읽기 전용으로 설정했는가가 문제일뿐이죠. 아니면 롬이라던가..

c언어는 다른 언어와 달리 형식에 대하여 자유로운 언어입니다... 흠.. 문자열형 등등을 따지며 엄격하게 다루려면.. 차라리 델파이나 자바가 어울리지 않을까 하네요. 그런식이라면 힘들게 c언어를 공부할 필요가 없겠죠. 좀 빠른 자바쯤이 되려나?

님ㅎ 즐~

doldori의 아바타

Re: c언어에 문자열형이 있던가요?

hanzo69 wrote:
c언어에 문자열형이 있던가요?
c언어에선 문자열형이란 없을텐데요.

hanzo69님 외에는 문자열형이라는 말을 쓴 사람이 없는데요?
말씀대로 C에는 문자열형이 없습니다. 지금 논의되는 대상을 가리켜 문자열 상수
(string literal)라는 용어를 쓰지요. 형을 따진다면 배열형입니다.

hanzo69 wrote:
"abcd"는 문자열형이 아니고 메모리 공간일 뿐이며, 평가형은 (const char *)형입니다. 이걸 건드리든 말던 그건 프로그래머 자유죠.

글쎄요. 컴파일이 된다는 이유로 이런 것을 자유라고 부를 수 있는지는 의문입니다.
비슷한 얘기로 널 포인터를 역참조하는 것도 자유라고 하시겠습니까?
그리고 평가형이라는 말도 처음 들어보는군요. "abcd"는 char[5]의 배열이며
char*로 변환될 수 있을 뿐입니다.

hanzo69 wrote:
"abcd"[0] = 0; 
이 코드는 "abcd" 자체가 상수가 아니라 (const char *) 형이 가리키는 데이터이므로 문법적으로 오류가 있을 뿐입니다.
((char *)"abcd")[0] = 0; 
char *p = "abcd";
p[0] = 0;
은 실제론 먼저의 코드와 같은 일을 하지만 문법적으론 아무 문제가 없는 코드죠. 단지 실행시에 오류가 날 뿐이죠.
정의되지 않은 동작이 아니고 a라는 문자의 위치에 0을 쓰려 시도를 합니다. 그리고 그 위치가 read-only라면 예외가 발생할 뿐이죠. 만약 롬과 램이 주소공간에 물린 아케이드 보드라면... 뭐 쓰기 시도가 무시되겠죠.

길게 설명하신 것을 C에서는 정의되지 않은 동작(undefined behavior)이라고 부릅니다.
참고로 C99 표준에서 관련된 내용을 인용합니다.
Quote:
6.4.5/6
[...] If the program attempts to modify such an array, the behavior is undefined.

hanzo69 wrote:
그리고 c언어 문법상으론 const 형은 자료형만 같다면 non-const 형에 대입할땐 자동 변환이 가능하도록 되어 있습니다.
char *p = (char *)"abcd"; // const char * 형을 char *형으로 변환
int i = (int)1; // const int형을 int형으로 변환
이렇게 명시적으로 변환하며 코딩하는 사람은 없죠. 
그리고 일단 변환된 이상은 건드리던 말던 시스템이 받아주는 한계 내에선 c의 문법 내에선 자유랍니다. 실행시 오류가 나면 나는거죠.

C가 프로그래머의 자유를 상당히 허용하는 편이긴 합니다만, 그렇다고 모든 자유를
허용하는 것은 아닙니다. 컴파일이 된다고 해서, 정의되지 않은 동작을 유발하는
코드가 우연히 의도대로 실행된다고 해서 이것을 자유라고 받아들이는 것은 곤란합니다.
정의되지 않은 동작을 유발하는 코드는 분명 잘못된 것입니다.

hanzo69 wrote:
세상의 모든 시스템이 "abcd"를 건드려선 안되는건 아닙니다. 건드려도 무방한 시스템에선 얼마든지 건드려도 된답니다.
오히려 리눅스가 특별한 경우라면 특별한 경우겠죠. 원래 읽기 쓰기가 가능한 메모리를 읽기만 가능하게 만들었으니까요.
윈도우에선 "abcd" 영역을 copy on write 속성을 지정하면 쓰기가 가능하니 뭐... 좀 다르다 해야 할라나?

어떤 코드가 특정 플랫폼에서 어떻게 구현되는지 아는 것도 도움이 되겠지만, 그 전에
언어의 정의를 바르게 이해하는 것이 우선이라고 봅니다. 이식성을 중요하게 생각한다면
당연히 그래야 하지 않겠습니까?

hanzo69 wrote:
그리고 전역변수던 상수든지간에 c언어 문법상으론 모든 상수를 얼마든지 수정할 수 있답니다. 포인터를 얻어 쓰기를 하면 그만이니까요. 단 운영체제가 그 상수가 기억된 메모리를 읽기 전용으로 설정했는가가 문제일뿐이죠. 아니면 롬이라던가..

상수는 l-value가 아니므로 그에 대한 주소를 취할 수 없습니다.
int* p = &0;
*p = 1;
이것은 운영 체제가 메모리를 읽기 전용으로 설정하건 말건 언어의 정의에 의해
잘못된 코드입니다.

hanzo69 wrote:
c언어는 다른 언어와 달리 형식에 대하여 자유로운 언어입니다... 흠.. 문자열형 등등을 따지며 엄격하게 다루려면.. 차라리 델파이나 자바가 어울리지 않을까 하네요. 그런식이라면 힘들게 c언어를 공부할 필요가 없겠죠. 좀 빠른 자바쯤이 되려나?

자유롭다고 해서 힘들게 C를 공부할 필요가 없을까요? 비교적 간단한 언어이긴 해도
제대로 이해하려면 꽤나 시간이 걸립니다.

'Language > C' 카테고리의 다른 글

이중 포인터의 필요성  (0) 2011.12.02
포인터 배열  (0) 2011.12.01
fopen, open 차이  (0) 2011.11.18
파일 퍼미션  (0) 2011.11.14
bsearch / 이진탐색  (0) 2011.11.09
:

fopen, open 차이

Language/C 2011. 11. 18. 08:37

파일 디스크립터와 파일 스트림

겉으로의 차이점은 open() 함수는 사용하는 파일을 구별하기 위해 파일 디스크립터라는 정수 번호로 지정하여 사용하는 반면 fopen()함수는 FILE 구조체 정보, 즉 파일 스트림 정보를 구합니다. 즉, 정수값만 구하는 open()함수 보다도 fopen()은 FILE 의 다양한 정보를 구하게 되는데 이것만 보더라도 open()계열 함수 보다 더 다양한 함수와 편리함을 제공합니다.

파일 디스크립터 파일 스트림

open()
close()
create()
read()
write()
lseek()
fcntl()

fopen()
fclose()
fgetc()
fputc()
fgets()
fputs()
fscanf()
fprintf()
fread()
fwrite()
ungetc()
feof()
ferror()
clearerr()
ftell()
rewind()
fseek()

그렇다고 open() 쪽의 함수가 필요없다는 것은 아닙니다. 시스템에 가까운 만큼 파일 이외에 장치를 사용하는 곳에서는 오히려 open()쪽의 함수가 더 편리할 수 있습니다.


이식성

이 외에도 C 표준 라이브러리를 사용하는 것이 이식성이 좋다는 것으로 알고 있습니다. 말 그대로 표준 라이브러리이니까요.

직 접 경험한 적은 없습니다만 비슷하게 보이는 유닉스 프로그램과 리눅스 프로그램도 시스템에 종속된 함수를 이용하면 소스를 그 시스템에 맞추어 다시 수정해 주어야하고, 때로는 매우 까다로운 경우도 있다고 하더군요. 대신에 C 표준 라이브러리만을 사용하면 이러한 변경작업이 매우 수월하다고 합니다.

대부분의 C 컴파일러는 표준을 준수하려고 합니다. 예로 아주 예전에 MS DOS 시절에 Turbo-C 에서는 fopen()과 함께 open()함수도 있어습니다. 그러나 MS Windows의 Visual C에서는 fopen()은 있는데, open() 함수는 없고 대신에 _open() 함수가 있는 것으로 알고 있습니다. 그러므로 가급적 표준 함수를 사용하는 것이 좋습니다.


이중 버퍼

fopen() 쪽의 함수는 C 표준 라이브러리에서 잡아주는 버퍼를 이용하며, open() 함수는 시스템에서 제공해 주는 버퍼를 이용합니다. 그러므로 C 표준 라이브러리인 fopen() 함수를 사용하게 되면 C 표준 라이브러리가 제공하는 버퍼와 함께 시스템에서 제공해 주는 버퍼를 사용하게 되어 실제 처리에서 버퍼를 이중으로 사용하게 됩니다.

시스템 버퍼가 있음에도 다시 C 라이브러리에서 버퍼를 제공하는 이유는 효율성을 높이기 위해서 입니다. 즉, 시스템 버퍼는 장치를 사용하기 위한 버퍼이므로 사정에 따라서는 버퍼에 있는 자료를 버려야하는 경우가 생길 수 있습니다.

그러나 C 라이브러리에서는 이런 문제점을 피하기 위해 버퍼를 하나 더 두고 시스템의 버퍼의 상태에 맞추어 입출력이 되도록 함으로서 프로그램 성능을 향상 시키고 안정성을 높여 줍니다.

[출처] open, fopen 차이|작성자 아무르

'Language > C' 카테고리의 다른 글

포인터 배열  (0) 2011.12.01
char *로 할당된 스트링값  (0) 2011.11.18
파일 퍼미션  (0) 2011.11.14
bsearch / 이진탐색  (0) 2011.11.09
stat  (0) 2011.11.08
:

파일 퍼미션

Language/C 2011. 11. 14. 20:55

S_IRUSR

소유자 읽기

S_IWUSR

소유자 쓰기

S_IXUSR

소유자 실행

S_IRWXU

소유자 모두가능

S_IRGRP

구룹 읽기

S_IWGRP

구룹 쓰기

S_IXGRP

구룹 실행

S_IRWXG

구룹 모두가능

S_IROTH

기타사용자 읽기

S_IWOTH

기타사용자 쓰기

S_IXOTH

기타사용자 실행

S_IRWXO

기타사용자 모두가능

S_ISUID

실행중 사용자ID설정

S_ISGID

실행중 구룹ID설정

[출처] [C언어]파일 퍼미션|작성자 수환이


'Language > C' 카테고리의 다른 글

char *로 할당된 스트링값  (0) 2011.11.18
fopen, open 차이  (0) 2011.11.18
bsearch / 이진탐색  (0) 2011.11.09
stat  (0) 2011.11.08
배열 크기 구하기  (0) 2011.11.08
:

bsearch / 이진탐색

Language/C 2011. 11. 9. 17:15

bsearch

 기능

 배열의 이진 탐색

 문법

 

 #include <stdlib.h>

 void *bsearch (const void *key, const void *base, size_t nelem, size_t width,

                       int (*fcmp)(const void*, const void*));

 

 프로토타입  stdlib.h 
 설명

 

 bsearch는 메모리내에서 nelem 원소들의 테이블(배열)을 탐색하고 테이블내에서 탐색키와 일치하는

 첫번째 요소(entry)의 어드레스를 리턴한다. 일치되는 것이 없을 때는 bsearch는 0을 리턴한다.

 형 size_t는 unsigned int로 정의된다.

 

    - nelem은 테이블에서 원소의 갯수를 준다.

    - width는 각 테이블 요소에서 바이트의 수를 지정한다.

 

 비교 루틴인 *fcmp는 두개의 인수 elem1과 elem2로 호출된다. 각 인수는 비교될 항목을 가리킨다.

 비교함수는 지적된 항목 (*elem1과 *elem2)을 비교하고 그 결과를 정수로 리턴한다.

 이 bsearch에서 *fcmp는 다음의 값을 리턴한다.

    <   0    만일 *elem1 < *elem2

    ==  0    만일 *elem1 == *elem2

    >   0    만일 *elem1 > *elem2

 

 전형적으로 elem1은 인수 key이고 elem2는 탐색될 테이블 내에서의 원소에 대한 포인터이다.

 

 리턴값

 bsearch는 탐색 key와 일치하는 테이블 내의 첫번째 요소의 어드레스를 리턴한다.

 이식성  UNIX 시스템상에서 사용하여 ANSI C와 호환성이 있다.
 참조  lfind, lsearch, qscrt
 예제

 

 #include <stdio.h>
 #include <stdlib.h>

 

 #define NELEMS(arr)  (sizeof(arr)  / sizeof(arr[0]))

 

 int numarray[] = {123, 145, 512, 627, 800, 993};

 

 int numeric(const void *p1, const void *p2)
 {
     return (*(int*)p1 - *(int*)p2);
 }

 

 /* Return 1 if key is in the table, 0 if not */
 int lookup(int key)
 {
     int *itemptr;

 

     /* bsearch() returns a pointer to the
         item that is found */
     itemptr = (int*)bsearch(&key, numarray, NELEMS(numarray), sizeof(int), numeric);
 
     return (itemptr != NULL);
 }

 

 int main()
 {
     printf("Is 512 in table? ");
     printf("%s\n", lookup(512) ? "YES" : "NO");

 

     return 0;
 }

 

 프로그램 출력

 

 Is 512 in table? YES

 

 

 

'Language > C' 카테고리의 다른 글

fopen, open 차이  (0) 2011.11.18
파일 퍼미션  (0) 2011.11.14
stat  (0) 2011.11.08
배열 크기 구하기  (0) 2011.11.08
exec 함수군  (0) 2011.11.07
:

stat

Language/C 2011. 11. 8. 14:23

#include<stdio.h>

#include<sys/types.h>

#include<sys/stat.h>

 

/**********************************

struct stat{

dev_t   st_dev;

ino_t   st_ino;

mode_t  st_mode;

nlink_t st_nlink;

uid_t   st_uid;

gid_t   st_gid;

dev_t   st_rdev;

off_t   st_size;

blksize_t st_blksize;

blkcnt_t st_blocks;

time_t  st_atime;

time_t  st_mtime;

time_t  st_ctime;

};

***********************************/

int main(int ac, char *av[])

{

    struct stat info;

 

    if( stat(av[1], &info) != -1 ){

        /*적재된파일시스템을위한장치.

        적재된각파일시스템은서로다른st_dev 값을가진다*/

        printf("device : %d\n", info.st_dev);

 

        /*해당파일시스템내에서그파일의아이노드번호.

        (st_dev, st_ino)쌍으로서로다른파일을구별한다*/

        printf("inode  : %d\n", info.st_ino);

 

        /*파일타입과접근허가가함께코드화되어있는필드*/

        printf("type and protection : %d\n", info.st_mode);

 

        /*이파일에대한하드링크의개수(링크개수).

        파일이열린후에링크가끊어졌다면(unlink) 이필드값은0이될수있다*/

        printf("number of hard links : %d\n", info.st_nlink);

 

        /*파일의UID(소유자번호)*/

        printf("user ID of owner : %d\n", info.st_uid);

 

        /*파일의GID(그룹번호)*/

        printf("group ID of owner : %d\n", info.st_gid);

 

        /*파일이블록또는문자장치일경우의장치타입.

        st_rdev는장치에관한정보를코드화한것이다.*/

        printf("device type (block or character device) : %d\n", info.st_rdev);

 

        /*파일의논리적인크기파일내에는여러개의구멍이있을수있으며,

        이경우에이크기는그파일이차지하고있는실제저장공간의크기를

        제대로반영하지못할수도있다*/

        printf("total size, in bytes : %d\n", info.st_size);

 

        /*파일의'블록크기'. 이필드는해당파일에대한I/O를위한

        적합한데이터블록의크기를나타낸다이값은거의모든경우에

        물리적인디스크섹터(sector)보다크다.

        linux ext2ext3 파일시스템에서이값은4096이다*/

        printf("blocksize for filesystem I/O : %d\n", info.st_blksize);

 

        /*이파일이사용하고있는'블록'의개수.

        linux에서이값은512 바이트블록단위이다*/

        printf("number of blocks allocated : %d\n", info.st_blocks);

 

        /*파일의데이터를마지막으로읽은시간*/

        printf("time of last access : %d\n", info.st_atime);

 

        /*파일의데이터를마지막으로쓰거나그크기를조정한시간*/

        printf("time of last modification : %d\n", info.st_mtime);

 

        /*파일의아이노드를마지막으로접근허가나

        소유자와같은파일의메타데이터가변경된시간*/

        printf("time of last inode change : %d\n", info.st_ctime);

    }

    else

        fprintf(stderr,"errror\n");

 

    return 0;

}

'Language > C' 카테고리의 다른 글

파일 퍼미션  (0) 2011.11.14
bsearch / 이진탐색  (0) 2011.11.09
배열 크기 구하기  (0) 2011.11.08
exec 함수군  (0) 2011.11.07
현재 날짜와 시간 출력  (0) 2011.11.04
:

배열 크기 구하기

Language/C 2011. 11. 8. 10:26
#include <stdio.h>

void trot(int trots[], int n);

void main()
{
    int aa[] = {1234567891011121314151617181920};
    int size = sizeof(aa) / sizeof(*aa); // 전체크기 / 원소크기 = 원소개수

    printf("size of %d\n", size);
    trot(aa, size);
}

void trot(int trots[], int n)
{
    int i;

    for(i = 0; i < n; i++)
        printf("%d\n", trots[i]);
}

'Language > C' 카테고리의 다른 글

bsearch / 이진탐색  (0) 2011.11.09
stat  (0) 2011.11.08
exec 함수군  (0) 2011.11.07
현재 날짜와 시간 출력  (0) 2011.11.04
gettimeofday  (0) 2011.11.04
:

exec 함수군

Language/C 2011. 11. 7. 18:38

execv 를 사용하는 프로그램이 있어서 이에 대한 예제 프로그램을 만들어 보았습니다. 2번째 포인트 배열의 맨 마지막을 NULL 로 넣어 주어야 하는 점만 주의하시면 될 것 같더군요.

 

01: #include <stdio.h>
02: #include <unistd.h>
03: #include <stdlib.h>
04: #include <errno.h>
05: 
06: int main( int argc, char * argv[] )
07: {
08:   char * pszArg[3];
09: 
10:   pszArg[0] = malloc( 255 );
11:   sprintf( pszArg[0], "/bin/ls" );
12: 
13:   pszArg[1] = malloc( 255 );
14:   sprintf( pszArg[1], "-al" );
15: 
16:   pszArg[2] = NULL;
17: 
18:   if( execv( pszArg[0], pszArg ) == -1 )
19:   {
20:     printf( "%d\n", errno );
21:   }
22: 
23:   return 0;
24: }


exec 함수군은 path나 file에 지정한 명령이나 실행 파일을 실행한다. 이때 arg나 envp로 시작하는 인자를 path나 file에 지정한 파일의 main 함수에 전달한다. 각 함수별로 경로명까지 지정하거나 단순히 실행 파일명만 지정하는 등 차이가 있고 인자를 전달하는 형태에도 차이가 있다.

 

#include<unistd.h>

int execl(const char *path, const char *arg0, ..., const char *argn, (char *)0);

path에 지정한 경로명의 파일을 실행하며 arg0~argn을 인자로 전달한다관례적으로 arg0에는 실행 파일명을 지정한다. execl함수의 마지막 인자로는 인자의 끝을 의미하는 NULL 포인터((char*)0)를 지정해야 한다. path에 지정하는 경로명은 절대 경로나 상대 경로 모두 사용할 수 있다.

int execv(const char *path, char *const argv[]);

path에 지정한 경로명에 있는 파일을 실행하며 argv를 인자로 전달한다. argv는 포인터 배열이다이 배열의 마지막에는 NULL 문자열을 저장해야 한다.

int execle(const char *path, const char *arg0, ..., const char *argn, (char *)0, char*const envp[]);

path에 지정한 경로명의 파일을 실행하며 arg0~argn envp를 인자로 전달한다. envp에는 새로운 환경 변수를 설정할 수 있다. arg0~argn을 포인터로 지정하므로마지막 값은 NULL 포인터로 지정해야 한다. Envp는 포인터 배열이다이 배열의 마지막에는 NULL 문자열을 저장해야 한다.

int execve(const char *path, char *const argv[], char *const envp[]);

path에 지정한 경로명의 파일을 실행하며 argv, envp를 인자로 전달한다. argv envp는 포인터 배열이다이 배열의 마지막에는 NULL 문자열을 저장해야 한다.

int execlp(const char *file, const char *arg0, ..., const char *argn, (char *)0);

file에 지정한 파일을 실행하며 arg0~argn만 인자로 전달한다파일은 이 함수를 호출한 프로세스의 검색 경로(환경 변수 PATH에 정의된 경로)에서 찾는다. arg0~argn은 포인터로 지정한다. execl 함수의 마지막 인자는 NULL 포인터로 지정해야 한다.

int execvp(const char *file, char *const argv[]);

file에 지정한 파일을 실행하며 argv를 인자로 전달한다. argv는 포인터 배열이다이 배열의 마지막에는NULL 문자열을 저장해야 한다.

'Language > C' 카테고리의 다른 글

stat  (0) 2011.11.08
배열 크기 구하기  (0) 2011.11.08
현재 날짜와 시간 출력  (0) 2011.11.04
gettimeofday  (0) 2011.11.04
소켓 정리  (0) 2011.11.02
:

현재 날짜와 시간 출력

Language/C 2011. 11. 4. 13:06
**************************************************************
   ( 현재 날짜와 시간 출력하는 예제 소스 )

   #include <stdio.h>
   #include <time.h>
   #include <sys/time.h>
   #include <unistd.h>

   int main(int argc, char *argv[])
   { 
        struct tm *tm;
        struct timeval tv;
 
        gettimeofday( &tv, NULL );
        tm = localtime( &tv.tv_sec );
 
        printf( "year    : (%d) \n", tm->tm_year +1900 );     // 년
        printf( "month  : (%d) \n", tm->tm_mon +1 );         // 월
        printf( "day     : (%d) \n", tm->tm_mday );           // 일
        printf( "hour    : (%d) \n", tm->tm_hour );             // 시
        printf( "minute : (%d) \n", tm->tm_min );             // 분
        printf( "scond : (%d) \n", tm->tm_sec );              // 초
 
        return EXIT_SUCCESS;
   }
**************************************************************

'Language > C' 카테고리의 다른 글

배열 크기 구하기  (0) 2011.11.08
exec 함수군  (0) 2011.11.07
gettimeofday  (0) 2011.11.04
소켓 정리  (0) 2011.11.02
getopt()와 optarg, optopt  (0) 2011.11.02
:

gettimeofday

Language/C 2011. 11. 4. 13:05

1장. gettimeofday(2)

차례
1.1. 사용법
1.2. 설명
1.3. 반환값
1.4. 에러
1.5. 예제
1.6. 참고문헌

현재 시간을 가져오고 시스템의 시간값을 설정한다.


1.1. 사용법

#include <sys/time.h>
#include <unistd.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);
int settimeofday(const struct timeval *tv ,  const  struct
             timezone *tz);
		


1.2. 설명

gettimeofday()은 time(2)와 매우 비슷하지만 마이크로초 단위의 시간 까지 되돌려준다. 현재는 time(2)를 대신해서 쓰이고 있으며, 가능한 time(2)대신 이 함수를 사용하는 걸 권장한다.

첫번째 인자인 tv는 현재 시스템 시간을 저장하기 위한 구조체로 다음과 같이 정의되어 있다.

struct timeval
{
    long tv_sec;       // 초
    long tv_usec;      // 마이크로초
}
		
두번째 인자인 tz은 타임존을 설정하기 위해서 사용된다.
struct timezone
{
    int tz_minuteswest:  // 그리니치 서측분차  
    int tz_dsttime       // DST 보정타입(일광 절약시간)
}
		
현재 timezone 구조체는 사용되지 않고 있으며, 앞으로도 지원되지 않을 것이다. 간혹 커널 소스등에서 이 필드가 사용되는 경우가 있는데, 모든 경우에 버그로 판단되어서 무시한다. 복잡하게 생각할 필요 없이 tz은 NULL을 사용하도록 한다.


1.3. 반환값

성공하면 0 실패하면 -1을 리턴한다.


1.4. 에러

EFAULT

tv나 tz이 접근할 수 없는 영역을 가리키고 있다.


1.5. 예제

#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
    struct timeval mytime;

    // 현재 시간을 얻어온다.
    gettimeofday(&mytime, NULL);
    printf("%ld:%ld\n", mytime.tv_sec, mytime.tv_usec);

    // 시간을 1시간 뒤로 되돌려서 설정한다.
    mytime.tv_sec -= 3600;
    settimeofday(&mytime, NULL);
    return 0;
}
		


1.6. 참고문헌

  1. Unix 시간 다루기

  2. time(2)

  3. stime(2)


'Language > C' 카테고리의 다른 글

exec 함수군  (0) 2011.11.07
현재 날짜와 시간 출력  (0) 2011.11.04
소켓 정리  (0) 2011.11.02
getopt()와 optarg, optopt  (0) 2011.11.02
시리얼 통신 - 자료 수신을 위한 poll  (0) 2011.09.16
: