window

#include <stdio.h>
#include <WinSock2.h>

#define PORT	7230
#define IP		"127.0.0.01"
#define MAXLINE	256

struct Msg {
	char data[MAXLINE];
	int length;
	int msgNum;
};

int main(int argc, char **argv) {
	WSADATA wsaData;
	SOCKET sockfd;
	struct sockaddr_in addr, recvAddr;
	int addrlen;
	int currentMsgNum = 0;
	struct Msg msg;

	if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
		return 1;
	}

	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
		return -1;
	}

	memset((void *)&addr, 0x00, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.S_un.S_addr = inet_addr(IP);
	addr.sin_port = htons(PORT);

	while(1) {
		memset(msg.data, 0x00, MAXLINE);
		printf(">> ");
		scanf("%s", msg.data);
		msg.length = htonl(strlen(msg.data));
		msg.msgNum = htonl(currentMsgNum++);

		addrlen = sizeof(addr);
		sendto(sockfd, (char *)&msg, sizeof(msg), 0, 
			(struct sockaddr *)&addr, addrlen);

		memset(msg.data, 0x00, MAXLINE);
		recvfrom(sockfd, (char *)&msg, sizeof(msg), 0,
			(struct sockaddr *)&addr, &addrlen);
		printf("SERVER >> %s\n", msg.data);
	}

	closesocket(sockfd);
	WSACleanup();
	return 0;
}


unix

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>

#define PORT 7230
#define MAXLEN 256

struct Msg {
	char data[MAXLEN];
	int length;
	int msgNum;
};

int main(int argc, char **argv) {
	int sockfd;
	socklen_t addrlen;
	struct Msg msg;
	struct sockaddr_in addr, cliaddr;
	int currentNum = 0;

	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		return 1;
	}

	memset((void *)&addr, 0x00, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	addr.sin_port = htons(PORT);

	addrlen = sizeof(addr);
	if(bind(sockfd, (struct sockaddr *)&addr, addrlen) == -1) {
		return -1;
	}

	printf("running...\n");
	while(1) {
		addrlen = sizeof(cliaddr);
		recvfrom(sockfd, (char *)&msg, sizeof(msg), 0,
				(struct sockaddr *)&cliaddr, &addrlen);
		printf("client >> %s\n", msg.data);

		memset((void *)&msg, 0x00, sizeof(msg));
		printf(">> ");
		scanf("%s", msg.data);
		msg.length = htonl(strlen(msg.data));
		msg.msgNum = htonl(currentNum++);

		printf("%s %d %d \n", msg.data, msg.length, msg.msgNum);
		sendto(sockfd, (void *)&msg, sizeof(msg), 0,
				(struct sockaddr *)&cliaddr, addrlen);

	}
	return 1;
}


#include <WinSock2.h>
#include <stdio.h>

#define BUFMAX 1024
#define GET_MSG "GET /index.html HTTP/1.0\n\n"
#define PORT 80

void printIPAddrs(char **h_addr_list);
// A. 실행인자로 도메인 이름을 받는다.
int main(int argc, char **argv) {
	WSADATA		WSAData;
	struct hostent *myent;
	SOCKADDR_IN addr;
	SOCKET s;
	char buffer[BUFMAX];
	int readbytes = 0;


	// B. 인터넷 주소를 가져오지 못할 경우 에러 처리.
	if(argc != 2) {
		printf("Usage : %s [ineternet address]\n", argv[0]);
		WSACleanup();
		return 1;
	}

	if (WSAStartup (MAKEWORD(2,2), &WSAData) != 0) {
		printf("WSAStartup failed\n");
		return 1;
	}

	myent = gethostbyname(argv[1]);
	if(myent == NULL) {
		printf("Not Found Domain Name.\n");
		return;
	}

	printf("Host Name : %s\n", myent->h_name);

	printIPAddrs(myent->h_addr_list);

	printf("=====================================================\n");

	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(s == INVALID_SOCKET) {
		return 1;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.S_un.S_addr = inet_addr(inet_ntoa(*(struct in_addr *)*myent->h_addr_list));
	
	printf("%s %d\n", inet_ntoa(*(struct in_addr *)*myent->h_addr_list), PORT);
	printf("%s\n", GET_MSG);

	printf("=====================================================\n");
	// D. 인터넷 주소 중 하나를 선택해서 웹 서버에 연결해서 웹페이지를 요청한다.(HTTP 프로토콜의 GET Method 이용)
	if(connect(s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
		printf("fail to connect\n");
		closesocket(s);
		return 1;
	}
	
	send(s, GET_MSG, sizeof(GET_MSG), 0);
	
	while(1){
		int i = 0;
		ZeroMemory(buffer, BUFMAX);
		i = recv(s, buffer, BUFMAX, 0);
		if(i <= 0) {
			break;
		}
		readbytes += i;
		printf("%s", buffer);	
	}
	printf("\ntotal length : %d\n", readbytes);

	closesocket(s);
	WSACleanup();
	return 0;

}

// C. 여러 개의 인터넷 주소가 있을 때, 이를 모두 출력한다.
void printIPAddrs(char **h_addr_list) {
	while(*h_addr_list != NULL) {
		printf("%s\n", inet_ntoa(*(struct in_addr *)*h_addr_list));	
		h_addr_list++;
	}
}


서버 실행환경

 

 학과 서버 사용

 OS

 SunOS 5.10

 GCC

 3.4.6

 Java

 1.5.0_16


클라이언트 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz 3.40GHz

 Memory

 8.00 GB

 OS

 Windows 7 Professional K 64bit

 Java

 1.8.0_05

 MySQL

 Ver 14.14 Distrib 5.6.19, for Win64

 Web Server

 Apache Tomcat 7.0.51


서버 프로그램

#include <stdio.h>
#include <sys/types.h> 	// socket, bind, accept, open
#include <sys/socket.h> // socket, bind, listen, accept
#include <unistd.h>		// read, write
#include <sys/stat.h> 	// open
#include <fcntl.h>		// open
#include <errno.h>

#include <string.h>

#define PORT	5500
#define MAXBUF	1024

int main() {
	int server_sockfd;
	int client_sockfd;
	int des_fd;	// file num
	struct sockaddr_in serveraddr, clientaddr;
	int client_len, read_len, file_read_len;	// length
	char buf[MAXBUF];
	
	
	int check_bind;
	

	client_len = sizeof(clientaddr);

	/* socket() */
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(server_sockfd == -1) {
		perror("socket error : ");
		exit(0);
	}

	/* bind() */
	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family		= AF_INET;
	serveraddr.sin_addr.s_addr	= htonl(INADDR_ANY);
	serveraddr.sin_port			= htons(PORT);

	if(bind(server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) > 0) {
		perror("bind error : ");
		exit(0);
	}

	/* listen */
	if(listen(server_sockfd, 5) != 0) {
		perror("listen error : ");
	}

	while(1) {
		char file_name[MAXBUF]; // local val
		memset(buf, 0x00, MAXBUF);
		
		/* accept() */
		client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, &client_len);
		printf("New Client Connect : %s\n", inet_ntoa(clientaddr.sin_addr));

		/* file name */
		read_len = read(client_sockfd, buf, MAXBUF);
		if(read_len > 0) {
			strcpy(file_name, buf);
			printf("%s > %s\n", inet_ntoa(clientaddr.sin_addr), file_name);
		} else {
			close(client_sockfd);
			break;
		}

		/* create file */
FILE_OPEN:
		des_fd = open(file_name, O_WRONLY | O_CREAT | O_EXCL, 0700);
		if(!des_fd) {
			perror("file open error : ");
			break;
		}
		if(errno == EEXIST) {
			close(des_fd);
			size_t len = strlen(file_name);
			file_name[len++] = '_';
			file_name[len++] = 'n';
			file_name[len] = '\0';
			goto FILE_OPEN;
		}
		
		/* file save */
		while(1) {
			memset(buf, 0x00, MAXBUF);
			file_read_len = read(client_sockfd, buf, MAXBUF);
			write(des_fd, buf, file_read_len);

			if(file_read_len == EOF | file_read_len == 0) {
				printf("finish file\n");
				break;
			}


		}


		close(client_sockfd);
		close(des_fd);
	}
	close(server_sockfd);
	return 0;
}


클라이언트 프로그램

#include <WinSock2.h>
#include <stdio.h>
#include <sys/types.h>
#include <io.h>
#include <sys/stat.h>
#include <fcntl.h>


#define PORT	5500
#define IP		"127.0.0.1"
#define MAXBUF	1024

int main() {
	WSADATA		WSAData;
	SOCKADDR_IN	addr;
	SOCKET		s;
	int			sourse_fd;
	char		buf[MAXBUF];
	int			file_name_len, read_len;
	
	if(WSAStartup(MAKEWORD(2,2), &WSAData) != 0) {
		return 1;
	}

	/* socket() */
	s = socket(AF_INET, SOCK_STREAM, 0);
	if(s == INVALID_SOCKET) {
		return 1;
	}

	addr.sin_family				= AF_INET;
	addr.sin_addr.S_un.S_addr	= inet_addr(IP);
	addr.sin_port				= htons(PORT);
	if(connect(s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
		perror("connect : ");
		printf("fail to connect.\n");
		closesocket(s);
		return 1;
	}

	memset(buf, 0x00, MAXBUF);
	printf("전송할 파일명 : ");
	scanf("%s", buf);

	printf(" > %s\n", buf);
	file_name_len = strlen(buf);

	send(s, buf, file_name_len, 0);
	sourse_fd = _open(buf, _O_RDONLY);
	if(!sourse_fd) {
		perror("Error : ");
		return 1;
	}
	
	while(1) {
		memset(buf, 0x00, MAXBUF);
		read_len = _read(sourse_fd, buf, MAXBUF);
		send(s, buf, read_len, 0);
		if(read_len == 0) {
			break;
		}
		
	}

	return 0;
}


서버 실행환경

 

 학과 서버 사용

 OS

 SunOS 5.10

 GCC

 3.4.6

 Java

 1.5.0_16


클라이언트 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz 3.40GHz

 Memory

 8.00 GB

 OS

 Windows 7 Professional K 64bit

 Java

 1.8.0_05

 MySQL

 Ver 14.14 Distrib 5.6.19, for Win64

 Web Server

 Apache Tomcat 7.0.51


서버 프로그램

#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>

#define PORT	5555
#define MAXBUF	1024 /* 클라이언트와 길이를 맞추어준다. */
int main(int argc, char **argv) {
	int server_sockfd, client_sockfd; // 소켓
	int client_len, n;
	int file_read_len;
	char buf[MAXBUF];
	char file_name[MAXBUF];
	struct sockaddr_in clientaddr, serveraddr;
	int source_fd; // 파일 번호
	int chk_bind; // 연결 확인 변수
	int chk_write;
	int read_len;

	client_len = sizeof(clientaddr);

	/* socket() */
	server_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(server_sockfd == -1) {
		perror("socket error : ");
		exit(0);
	}

	/* bind() */
	bzero(&serveraddr, sizeof(serveraddr)); // 해당 메모리 영역 초기화
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serveraddr.sin_port = htons(PORT);

	chk_bind = bind(server_sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
	if(chk_bind > 0) {
		perror("bind error : ");
		exit(0);
	}

	/* listen() */
	if(listen(server_sockfd, 5)) {
		perror("listen error : ");
	}

	/* 클라이언트 연결 대기 */
	while(1) {
		memset(buf, 0x00, MAXBUF);
		/* accept() */
		client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr, &client_len);
		printf("New Client Connect: %s\n", inet_ntoa(clientaddr.sin_addr));
		
		/* 파일명 받기 */
		read_len = read(client_sockfd, buf, MAXBUF);
		if(read_len > 0) {
		    memset(file_name, 0x00, MAXBUF);
			strcpy(file_name, buf);
			printf("%s > %s\n", inet_ntoa(clientaddr.sin_addr), file_name);
		} else {
			close(client_sockfd);
			break;
		}

		/* 파일 열기  */
		source_fd = open(file_name, O_RDONLY); 
		if(!source_fd) {
			perror("file open error : ");
			break ;
		}
		printf("before while\n");
		while(1) {
			memset(buf, 0x00, MAXBUF);
			file_read_len = read(source_fd, buf, MAXBUF);
			printf("\nread : %s",buf); 
			chk_write = write(client_sockfd, buf, MAXBUF);
			if(file_read_len == EOF | file_read_len == 0) {
				printf("finish file\n");
				break;
			}
		}
		close(client_sockfd);
		close(source_fd);
	}
	close(server_sockfd);
	return 0;
}


클라이언트 프로그램

#include <WinSock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h> // _open(), _read() 사용하기 위해서
#include <fcntl.h> // O_CREATIO, _O_RDONLY 사용하기 위해
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h> // _S_IWRITE 사용하기 위해

#define PORT	5555
#define IP		"127.0.0.1"
#define MAXBUF	1024

int main() {
	WSADATA		WSAData;
	SOCKADDR_IN addr;
	SOCKET		s;
	char buffer[1024];
	char file_name[1024];
	int readbytes;
	int i, len;
	int dest_fd;
	int recv_len;
	int totaln = 0;

	if (WSAStartup (MAKEWORD(2,2), &WSAData) != 0) {
		return 1;
	}

	s = socket(AF_INET, SOCK_STREAM, 0);

	if (s == INVALID_SOCKET) {
		return 1;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons(PORT);
	addr.sin_addr.S_un.S_addr = inet_addr(IP);

	if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
		printf("fail to connect\n");
		closesocket(s);
		return 1;
	}

	printf("전송받을 파일명 : ");
	scanf("%s", file_name);

	printf("입력한 파일명 : %s", file_name);
	len = strlen(file_name);
	
	send(s, file_name, len, 0);
	
	// 파일 생성
	dest_fd = _open(file_name, _O_CREAT | _O_EXCL | _O_WRONLY,_S_IWRITE);
	if(!dest_fd) {
		perror("Error ");
		return 1;
	}
	
	if(errno == EEXIST) {
		perror("Error ");
		_close(dest_fd);
		return 1;
	}
	printf("파일 생성 완료\n");


	while(1) {
		memset(buffer, 0x00, MAXBUF);
		recv_len = recv(s, buffer, MAXBUF, 0);
		if(recv_len == 0) {
			printf("finish file\n");
			break;
		}
		totaln += _write(dest_fd, buffer, recv_len);
	}
	_close(dest_fd);
	 
	closesocket(s);
	WSACleanup();

	//system("pause");
	return 0;

}




라이브러리 ws2_32.lib 추가해주고 실행해야한다.

#include <WinSock2.h>
#include <stdio.h>

void ptintMyent(struct hostent *myent);

int main(int argc, char **argv) {
	WSADATA		WSAData;

	if (WSAStartup (MAKEWORD(2,2), &WSAData) != 0) {
		return 1;
	}

	ptintMyent(gethostbyname("web.dongguk.ac.kr"));
	ptintMyent(gethostbyname("www.naver.com"));
	ptintMyent(gethostbyname("www.hanb.co.kr"));

	WSACleanup();
	return 0;

}

void ptintMyent(struct hostent *myent) {
	long int *add;
	SOCKADDR_IN myen;

	if(myent == NULL) {
		return;
	}

	printf("Host name : %s\n", myent->h_name);

	while(*myent->h_addr_list != NULL) {
		add = (long int*)*myent->h_addr_list;
		myen.sin_addr.S_un.S_addr = *add;
		
		printf("%d -> %s\n", add, inet_ntoa(myen.sin_addr));
		myent->h_addr_list++;
	}
	printf("\n");
}


문자 -> 숫자

#include 
char *str = NULL;
int result;
str = "1234";
result = atoi(str);

숫자 -> 문자

atoi()와 달리 itoa()는 표준이아니다. 그렇기때문에 itoa()는 유닉스에서 사용할 수가 없다. 유닉스에서는 sprintf()를 사용한다.

(여담이지만 네트워크 프로그래밍 중간 시험에서 서버에서 숫자로 된 값을 클라이언트(window)로 전송해야하는데 itoa() 밖에 몰라서 한 문제를 날려먹었다... '아는 것이 힘이다.'라는 것을 느낀 시험이었다.)

WINDOW
int val = 1234;
char* str = NULL;
_itoa(val, str, 10)
UNIX
char str[512];
int val = 1234;
sprintf(str, "%d", val);


2의 보수로 나눗셈

  1 #include <stdio.h>
  2
  3 int main() {
  4     int val1;
  5     int val2;
  6     int answer = 0; // 몫
  7     int remainder = 0; // 나머지
  8
  9     val1 = 198;
 10     val2 = 75;
 11     printf("%d / %d =\n", val1, val2);
 12
 13     val2 = ~val2 + 1; // 2의 보수
 14     printf("%d\n", val2);
 15
 16     while(1) {
 17         val1 += val2;
 18         if(val1 < 0)
 19             break;
 20         answer++;
 21         remainder = val1;
 22     }
 23     printf("answer is %d, remainder %d\n", answer, remainder);
 24
 25     return 0;
 26 }


유닉스에서 파일 목록 출력하기

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include <error.h>
 
int main()
{
    DIR *dir;
    struct dirent *ent;
    dir = opendir ("./");
    if (dir != NULL) {
 
    /* print all the files and directories within directory */
    while ((ent = readdir (dir)) != NULL) {
        printf ("%s\n", ent->d_name);
    }
    closedir (dir);
    } else {
         /* could not open directory */
         perror ("");
        return EXIT_FAILURE;
    }
}


윈도우에서 파일 목록 출력하기

#include <stdio.h>
#include <io.h>
#include <conio.h>
 
void main()
{
    _finddata_t fd;
    long handle;
    int result = 1;
    handle = _findfirst(".\\*.*", &fd);  //현재 폴더 내 모든 파일을 찾는다.
 
    if (handle == -1)
    {
        printf("There were no files.\n");
        return;
    }
 
    while (result != -1)
    {
        printf("File: %s\n", fd.name);
        result = _findnext(handle, &fd);
    }
 
    _findclose(handle);
    return;
}

출처 링크, 링크


문제점

Microsoft Visual Studio 2010 컴파일시 에러 발생

"COFF로 변환하는 동안 오류가 발생했습니다. 파일이 잘못되었거나 손상되었습니다."


해결방안

프로젝트 속성 > 구성 속성 > 링커 > 일반 > 중분 링크 사용 > 아니요(/INCREMENTAL:NO)
혹은
프로젝트 속성 > 구성 속성> 매니페스트 도구 > 입력 및 출력 > 매니페스트 포함 > 아니요
영구적으로 해결하는 방법
-> Visual Studio 서비스팩 1 다운로드



 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz 3.40GHz

 Memory

 8.00 GB

 OS

 Windows 7 Professional K 64bit

 Java

 1.8.0_05

 MySQL

 Ver 14.14 Distrib 5.6.19, for Win64

 Web Server

 Apache Tomcat 7.0.51


문제점

컴파일시 아래와 같은 에러 중 어느 한가지라도 발생했을 경우.(확실치는 않다.)

Warning    2    warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    336    1    Programa 3205
Warning    3    warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    363    1    Programa 3205
Warning    4    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    369    1    Programa 3205
Warning    5    warning C4996: 'fscanf': This function or variable may be unsafe. Consider using fscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    371    1    Programa 3205
Warning    6    warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    374    1    Programa 3205
Warning    7    warning C4996: 'strtok': This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    375    1    Programa 3205
Warning    9    warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    718    1    Programa 3205
Warning    10    warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    727    1    Programa 3205
Warning    11    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    729    1    Programa 3205
Warning    12    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    754    1    Programa 3205
Warning    13    warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    766    1    Programa 3205
Warning    14    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    768    1    Programa 3205
Warning    15    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    792    1    Programa 3205
Warning    16    warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    806    1    Programa 3205
Warning    17    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    808    1    Programa 3205
Warning    18    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    830    1    Programa 3205
Warning    19    warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    842    1    Programa 3205
Warning    20    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    844    1    Programa 3205
Warning    21    warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    866    1    Programa 3205
Warning    22    warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    911    1    Programa 3205
Warning    23    warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    f:\fernando luiz\teste-3205\ps3000.c    939    1    Programa 3205

해결방안


Project properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions > _CRT_SECURE_NO_WARNINGS
프로젝트 오른쪽 클릭 > 속성 > 구성 속성 > C/C++ > 전처리기 > 전처리기 정의 > _CRT_SECURE_NO_WARNINGS 추가.

보안상의 문제로 다른 함수를 사용하라는 것인데 설정 추가로 해결할 수 있다.

 실행환경

 Desktop

 조립식

 CPU

 Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz 3.40GHz

 Memory

 8.00 GB

 OS

 Windows 7 Professional K 64bit

 Java

 1.8.0_05

 MySQL

 Ver 14.14 Distrib 5.6.19, for Win64

 Web Server

 Apache Tomcat 7.0.51


문제점

유닉스에서 사용하던 함수 open(), close(), write(), read()를 window Visual Studio 에서 사용하려하는데 에러 발생.

해결방안

_open()을 사용한다. 다른 함수 모두 앞에 '_'를 붙혀 사용한다. 아래 코드는 MS Developer Network C 라이브러리에서 참고하였다.

#include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <io.h> #include <stdio.h> int main( void ) { int fh1, fh2; fh1 = _open( "CRT_OPEN.C", _O_RDONLY ); // C4996 // Note: _open is deprecated; consider using _sopen_s instead if( fh1 == -1 ) perror( "Open failed on input file" ); else { printf( "Open succeeded on input file\n" ); _close( fh1 ); } fh2 = _open( "CRT_OPEN.OUT", _O_WRONLY | _O_CREAT, _S_IREAD | _S_IWRITE ); // C4996 if( fh2 == -1 ) perror( "Open failed on output file" ); else { printf( "Open succeeded on output file\n" ); _close( fh2 ); } }


참고 사이트 링크


C 연산자 우선순위

  1. 1차 연산자 : (), [], ->, .
  2. 단항 연산자 : !, ~, ++, --, +, -, (type), *, &, sizeof
  3. 곱셈, 나눗셈 : *, /, %
  4. 덧셈, 뺄셈 : +, -
  5. 쉬프트 연산자 : <<, >>
  6. 관계 연산자 : <, <=, >, >=
  7. 등가 연산자 : ==, !=
  8. 비트 연산자 : &, |
  9. 논리 연산자 : &&, ||
  10. 조건 연산자 : ?:
  11. 배정 연산자 : =, +=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=
  12. 콤마 연산자 : ,


Visual studio 코드 자동 정렬

Ctrl + K + F or Alt + F8

'대학 생활 > C' 카테고리의 다른 글

[C] 유닉스의 open()를 대신하는 메서드  (0) 2014.10.09
[C] 연산자 우선순위  (0) 2014.05.02
[C] error C4996: 'fopen': This function ... 에러  (2) 2014.03.12
[C++]ifstream 클래스  (0) 2013.10.31

문제점

코드 작성중 fopen에서 에러발생.


해결방안

두개의 방법중 하나를 선택한다.

1. fopen_s()를 사용한다.

FILE* fp;
fopen_s(&fp, "c:\test.txt", "rw");


2. _CRT_SECURE_NO_WARINGS 허용한다.

프로젝트 오른쪽 클릭 후 속성에서 전처리게 정의에 추가한다.


'대학 생활 > C' 카테고리의 다른 글

[C] 연산자 우선순위  (0) 2014.05.02
[VS] Visual studio 코드 자동 정렬  (0) 2014.04.24
[C++]ifstream 클래스  (0) 2013.10.31
[C] 성적표 출력하기(파일읽기 scanf함수)  (0) 2013.10.16

인터넷 어디선가 퍼온 ifstream 클래스

 

Public 멤버

생성자 - 객체를 생성하며 부가적으로 파일과 연관시킬 수 있다.
rdbuf : filebuf 객체를 얻는다.
is_open : 파일이 열려있는지 확인한다.
open : 파일을 연다.
close : 파일을 닫는다.

istream 으로 부터 상속 받은 멤버들

operator>> : 서식화된 데이터를 추출(입력)한다.
gcount : 마지막 서식화 되지 않은 입력에서 받아들였었던 문자의 개수를 구한다.
get : 스트림으로 부터 서식화 되지 않은 데이터를 얻는다.
getline : 스트림으로 부터 한 줄을 입력받는다.
ignore : 문자들을 입력 받고 지운다.
peek : 그 다음으로 추출될 문자를 얻어온다.
read : 데이터 블록을 읽는다.
readsome : 버퍼에서 읽기 가능한 데이터 블록을 읽어온다.
putback : 문자를 다시 집어넣는다.

unget : get pointer 을 감소 시킨다.
tellg : get pointer 의 위치를 얻는다.
seekg : get pointer 의 위치를 설정한다.
sync : 입력 버퍼를 문자들의 소스에 동기화 시킨다.
sentry : 예외로 부터 안전한 접두/접미 작업을 수행한다. (클래스)

ios 로 부터 상속 받은 함수들

good : 스트림의 상태가 입출력 작업을 할 수 있는지 확인한다.
eof : eof 비트가 설정되었는지 확인한다.
fail : fail 비트나 bad 비트가 설정되었는지 확인한다.
bad : bad 비트가 설정되었는지 확인한다.
operator! : 스트림 객체에 오류 플래그(fail 비트나 bad 비트)가 설정되었는지 확인한다.
operator void* : 포인터로 변환한다.
rdstate : 오류 상태 플래그(error state flag)를 얻어온다.
setstate : 오류 상태 플래그를 설정한다.
clear : 오류 상태 플래그들을 설정한다
copyfmt : 서식 정보를 복사한다.
fill : 채우기 문자(fill character) 을 얻거나 설정한다.
exceptions : 예외 마스크를 얻거나 설정한다.
imbue : 로케일을 설정한다.

tie : 엮어진 스트림(tied stream)을 얻거나 설정한다.

rdbuf : 연관된 스트림 버퍼를 얻거나 설정한다.
narrow : 표준 char 형으로 문자를 변환한다.
widen : 표준 wchar_t 형으로 문자를 변환한다.

ios_base 로 부터 상속된 함수들

flags : 서식 플래그를 수정하거나 얻어온다.
setf : 특정 서식 플래그를 설정한다.

unsetf : 특정 서식 플래그를 초기화 한다.

precision : 부동 소수점 정밀도를 수정하거나 얻어온다.

width : 필드의 너비를 수정하거나 얻어온다
imbue : 로케일을 채운다.
getloc : 현재 로케일을 얻어온다
xalloc : 내부 확장 가능 배열의 새로운 인덱스를 리턴한다. (정적 함수)
iword : 내부 확장 가능 배열의 특정 정수 원소의 레퍼런스를 얻는다.
pword : 내부 확장 가능 배열의 포인터의 레퍼런스를 얻는다.
register_callback : 이벤트 콜백 함수를 등록한다.
sync_with_stdio : iostream 과 cstdio 스트림과의 동기화를 활성화 하거나 비활성화 한다.

먼저 학번과 성적이 저장된 파일이 존재해야한다.
/*
    목적 : 파일을 읽어 각 반의 학생의 성적과 합계, 평균을
   		  구하고 각 과목의 반평균을 구한다.
    작성날짜 : 2013.09.23
 */
#include <stdio.h>
#include <stdlib.h>

// 상수들 
#define PEPLE_NUM 181	// 총학생수 정의

void openFile(FILE* fp);
void printClass(int class);

// 학생 정보를 저장하기 위한 구조체 선언
typedef struct student{
	char class_st[10];
	int class[3];
	int score[5];
	int total;
	float average;
} Student;

// 모든 함수에서 사용하기 위해 전역부에 선언
Student stu[PEPLE_NUM];

int main(int argc, char *argv[]) {
	
	FILE* fp = fopen("scr2013.txt", "r");
	if (fp == NULL) {
		printf(" File is null.\n");
		return -1;
	}
	openFile(fp);
	fclose(fp);

	printf("┌──────────────────────┐\n");
	printf("│  초등학교 1학년 성적 일람표 출력하기.  │\n");
	printf("└──────────────────────┘\n");

	while(1) {
		int in = 0;
		printf("  어느 반을 출력할 것입니까?(exit=0) : ");
		scanf("%d", &in);

		if(in == 0) {
			printf("program exit...\n");
			break;
		}
		// 성적일람표 출력 함수 실행
		printClass(in);
	} // while

	return 0;
}

/* =============== openFile ======================================
  파일을 읽어서 구조체 배열에 저장하고 총점, 평균 구하는 함수
	사전조건 : main에서 읽은 파일을 배열에 입력하기 위해서
			   매개변수 fp로 받아온다.
 	사후조건 : 구조체 배열에 점수를 입력하고 총점, 평균을 구한다.
 */
void openFile(FILE* fp) {
// 지역정의
	int temp;
	int i;

// 문장들
	// 파일 읽어서 구조체 배열에 입력하기
	for(i=0; i < PEPLE_NUM; i++) {
		fscanf(fp, "%s %d %d %d %d %d", &(stu[i]).class_st, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2], &stu[i].score[3], &stu[i].score[4]);

		// 입력받은 문자열인 학번을 integer로 변환하기 위해 atoi함수를 사용했다.
		temp = atoi(stu[i].class_st);
		stu[i].class[0] = temp / 10000;
		stu[i].class[1] = (temp - (stu[i].class[0] * 10000)) / 100;
		stu[i].class[2] = (temp - (stu[i].class[0] * 10000) - (stu[i].class[1] * 100)) / 1;
	}

	// 입력받은 점수로 총점, 평균 계산하기
	for(i = 0; i < PEPLE_NUM; i++) {
		stu[i].total = stu[i].score[0] + stu[i].score[1] + stu[i].score[2] + stu[i].score[3] + stu[i].score[4];
		stu[i].average = stu[i].total / 5.0;
	}

} // openFile
//================= openFile End =================================


/* =============== printClass  ===================================
   출력하고자 하는 반을 주어진 틀에 맞게 출력하는 함수.
     사전조건 : 출력하고자하는 반을 매개변수로 받는다.
	 사후조건 : 헤더를 출력하고 학생들의 정보를 모두 출력한다.
	 			모두 출력하고 난뒤에 각 과목의 반평균을 출력한다.
 */
void printClass(int class) {
// 지역정의
	int i;
	int count = 0;
	float kor = 0;
	float math = 0;
	float social = 0;
	float science = 0;
	float pe = 0;

// 문장들
	printf("\n  1 학년 %2d 반 성적일람표\n", class);
	printf(" 학번  국어  산수  사회  과학  체육  총점  평균 \n");
	printf("------------------------------------------------\n");
	// 학생 출력.
	for(i = 0; i < PEPLE_NUM ;i++ ) {
		if(stu[i].class[1] == class) {
			printf("%5s  %3d   %3d   %3d   %3d   %3d   %3d   %3.1f \n", stu[i].class_st, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].score[3], stu[i].score[4], stu[i].total, stu[i].average);
			kor += stu[i].score[0];
			math += stu[i].score[1];
			social += stu[i].score[2];
			science += stu[i].score[3];
			pe += stu[i].score[4];
			count++;
		}
	}
	// 학생이 없을 경우 출력.
	if(count == 0) {
		printf("               자료가 없습니다.\n\n");
		return;
	}

	printf("------------------------------------------------\n");
	printf("반평균  %3.1f  %3.1f  %3.1f  %3.1f  %3.1f \n\n", kor/(float)count, math/count, social/count, science/count, pe/count);
} // printClass
//================= printClass End ===============================


/* squential search, binary search
   단어 찾기 프로그램
	작성자 : 김영준
	날짜 : 2013/10/3
*/
#include <stdio.h>
#include <string.h>

// 전역선언
typedef struct words {
	char words[30];	// 파일중 제일 긴 단어 22자
} Words;

const int MAX_SIZE = 26000;

// 기본형선언
void readWords(Words* wordsArray, int* last);
void seqSearcah(Words wordsArray[], int last); 
void binarySearch(Words wordsArray[], int last);

int main(void) {
// 지역정의 
	Words wordsArray[MAX_SIZE];
	int last = 0;

// 문장들
	readWords(wordsArray, &last);
	seqSearch(wordsArray, last);
	printf("\n");
	binarySearch(wordsArray, last);
	return 0;
} // main

/* ================= readWords =================
	파일을 읽어서 배열에 적재한다.
	사전조건		wordsArray는 채워져야 할 배열
				last는 마지막 요소의 인덱스
	사후조건		배열이 채워짐
*/
void readWords(Words* wordsArray, int* last) {
// 지역변수
	char buf[256];
	FILE* fp = fopen("/usr/dict/words", "r");

// 문장들
	if(fp == NULL) {
		printf("File is null\n");
		exit(1);
	}

	printf("단어 읽는 중");
	while(fgets(buf, sizeof(buf), fp) != NULL) {
			//개행문자 삭제
			buf[strlen(buf)-1] = 0;
			// 문자열 복사 함수 strcpy() 사용.
			strcpy(wordsArray[*last].words, buf);
			(*last)++;
			if(*last % 1000 == 0) {
				printf(".");
			}
	}
	printf("%d 단어의 사전 구축 완료\n", *last);
	fclose(fp);
} // readWords

/* ================= seqSearch =================
	순차적 찾기로 목표를 찾는다.
	모두 찾고나면 결과를 출력한다.
	사전조건		wordsArray는 데이터를 가지고 있는 배열
				last는 마지막 요소의 인덱스
*/
void seqSearch(Words wordsArray[], int last) {
	int looker;
	char target[256];

	printf("영어 단어 찾기(Sequential Search)\n");
	printf("==================================\n");

	while(1) {
		looker = 0;
		printf("단어 입력(quit:ESC) : ");
		fgets(target, sizeof(target), stdin);
		// 개행문자 삭제
		target[strlen(target)-1] = 0;

		if(target[0] == 27){
			printf("Program quit...\n");
			break;
		}

		// seqSearch
		while(looker < last && strcasecmp(target, wordsArray[looker].words)) {
			looker++;
		}

		// 결과 출력
		if(!strcasecmp(target, wordsArray[looker].words)) {
			printf("단어 %s 찾음 비교횟수 : %d\n", target, looker+1);
		} else {
			printf("단어 %s 찾기실패 비교횟수 : %d\n", target, looker+1);
		}
	}

	printf("==================================\n");
	printf("Sequential search 끝\n");

} // seqSearch

/* ================= binarySearch =================
	이진 찾기로 목표를 찾는다.
	모두 찾고나면 결과를 출력한다.
	사전조건		wordsArray는 데이터를 가지고 있는 배열
				last는 마지막 요소의 인덱스
*/
void binarySearch(Words wordsArray[], int end) {
// 지역변수
	int looker;
	char target[256];
	int first, mid, last;
	int cnt = 0;

// 문장들
	printf("영어 단어 찾기(binary Search)\n");
	printf("==================================\n");
	
	while(1) {
		looker = 0;
		first = 0;
		last = end;
		cnt = 0;

		printf("단어입력(quit:ESC) : ");
		fgets(target, sizeof(target), stdin);
		// 개행문자 삭제
		target[strlen(target)-1] = 0;

		if(target[0] == 27) {
			printf("Program quit...\n");
			break;
		}

		// binarySearch
		while( first <= last) {
			mid = (first + last) / 2;
			if(0 < strcasecmp(target, wordsArray[mid].words)) {
				first = mid + 1;
			} else if(0 > strcasecmp(target, wordsArray[mid].words)) {
				last = mid - 1;
			} else {
				break;
			}
			cnt++;
		}

		// 결과 출력
		if(!strcasecmp(target, wordsArray[mid].words)) {
			printf("단어 %s 찾음 비교횟수 : %d\n", target, cnt+1);
		} else {
			printf("단어 %s 찾기실패 비교횟수 : %d\n", target, cnt+1);
		}

	}

	printf("==================================\n");
	printf("Sequential search 끝\n");
} // binarySearch


인터넷에 검색하면 많이 나오는 코드이다.

하지만 컴퓨터가 너무 빠른이유인지 모르겠지만... 0초가 나온다.


#include <stdio.h>
#include <time.h>

int main(void) {
    clock_t start, end;
    double timechk;

    start = clock();

    int i;
    for(i = 0; i < 20000; i++) {
        //실행할 문장들
    }

    end = clock();
    timechk = (double)(end - start) / CLOCKS_PER_SEC;
    printf("time : %f\n", timechk);

    return 0;
}


다음은 결과값이 나온 코드이다. 정확한지는 모르겠지만 결과는 나온다... 우선 이걸로 측정해야겠다.
#include <stdio.h>
#include <sys/time.h>

int main(void) {
    struct timeval start, end;
    double timechk;

    // 현재시간
    gettimeofday(&start, NULL);

    int i;
    for(i = 0; i < 10000; i++) {}

    // 계산
    gettimeofday(&end, NULL);
    timechk = (double)(end.tv_sec) + (double)(end.tv_usec) / 1000000.0 -
        (double)(start.tv_sec) - (double)(start.tv_usec) / 1000000.0;
    printf("%f\n", timechk);

    return 0;
}


헤더 : string.h

기능 : 문자열을 구분자로 나누어준다.

char* strtok(char* strToken, const char* strDelimit);


strtok() 함수는 내부적으로 검색한 위치를 기억하고 있으므로, 다음번에 실행할 땐 다음 위치부터 검색한다.



#include <stdio.h>
#include <string.h>
#define TOKEN ","

int main(void) {
    char* temp;
    char str[] = "string,int";
    temp = strtok(str, TOKEN);

    printf("str : %s\n", str);
    printf("temp : %s\n", temp);

    temp = strtok(NULL, TOKEN);
    printf("str : %s\n", str);
    printf("temp : %s\n", temp);

    return 0;
}



대소문자를 구분하지 않고 문자열을 비교한다.

char* strcasecmp(const char *s1, const char *s2, size_t n);

헤더 : string.h

매개변수 : s1 -> 비교할 대상, s2 -> 대상과 비교할 문자열

리턴값 : 값 == 0    // s1 == s2

값 > 0    // s1 < s2

값 < 0    // s1 > s2

+ Recent posts