C언어 구조체 포인터로 멤버의 주소에 접근해서 scanf 혹은 strcpy 사용
글쓴이: 익명 사용자 / 작성시간: 토, 2018/09/01 - 8:22오후
안녕하세요! C언어 예제를 풀다가 구조체 포인터를 다른 함수로 전달한 뒤 포인터를 이용해서 char 배열에 값을 입력하는데서 궁금한 점이 생겨서 질문을 드려봅니다!
예제는 책 정보를 저장하고 출력하는 간단한 건데요...
#include <stdio.h> #include <stdlib.h> #include <string.h> #define debugmode 1 //구조체 정의 typedef struct{ char title[30]; char author[30]; int page; }bookInfo; void inputInfo(bookInfo * info); void outputInfo(bookInfo * info); int main() { //local declaration bookInfo * info = NULL; int numBook = 0, i = 0; //statements printf("How many books do you want to tag? put numbers: "); info = (bookInfo *)malloc((sizeof(bookInfo)*numBook)); //input info for(i=0; i < numBook; i++){ printf("Input book #%d\n", i+1); inputInfo(info+i); } //output info puts("\nThe result of the addition\n"); for(i=0; i < numBook; i++){ printf("Input book #%d\n", i+1); outputInfo(info+i); } return 0; }//main void inputInfo(bookInfo * info){ #if debugmode == 1 strcpy((info->author),"debugAuthor"); strcpy((info->title),"debugTitle"); info->page = 10; #else fputs("Title: ",stdout); scanf("%s", &(info->title)); fputs("Author: ",stdout); scanf("%s", &(info->author)); fputs("page: ",stdout); scanf("%d", &(info->page)); #endif // debugmode } void outputInfo(bookInfo * info){ printf("Title: %s\n",info->title); printf("Author: %s\n", info->author); printf("Page: %d\n\n", info->page); }
제가 궁금한 부분은 void inputInfo(bookInfo * info) 함수 부분에 있어요. 디버깅할 때마다 실행시키고 구조체의 char 부분을 일일히 인풋을 입력하기가 귀찮아서... 바로 입력되게 매크로를 사용했습니다. 매크로에서는 바로 char을 바로 입력시키려고 strcpy 함수를 사용했고, 직접 입력할 때는 scanf 함수를 사용했습니다.
그런데 strcpy 함수나 scanf함수 모두 (char *)type, 그러니까 주소값을 인풋으로 받아야 하잖아요?
그런데 제 경우는
strcpy(&(info->author),"debugAuthor"); scanf("%s", &(info->title));
의 경우에는 strcpy에서 이런 경고가 나와요; note: expected 'char *' but argument is of type 'char (*)[30]'
그리고 만약에
strcpy((info->author),"debugAuthor"); scanf("%s", (info->title));
으로 둘다 &을 없애고 실행을 하면 for반복문에서 1번만 입력을 받고 바로 프로그램이 끝나는 런타임 에러가 발생하고요...
프로그램이 짠 의도대로 작동하게 하려면
strcpy((info->author),"debugAuthor"); scanf("%s", &(info->title));
scanf함수에만 &을 붙여줘야 합니다...;;
제 생각에는 info->author은 구조체의 author[30]의 값에 접근을 하는 거니까 그냥 일반적으로 char type에 값을 입력하는 것처럼 두번째 경우처럼 두 함수 다 &가 없어야 할 것 같은데 왜 이런 현상이 발생할까요 ㅜㅜ 그리고 구조체 포인터를 통해서 멤버에 접근해서 그 멤버의 주소를 알기 위해 &을 붙여주면 어째서 컴파일러는 그냥 char 배열이 아니라 char * 배열로 인식하는 건지 선배님들의 가르침 부탁드립니다 ㅜㅜ
Forums:
앗... 코드가 조금 잘못되었네요...
bookInfo * info = NULL;
이 부분이
bookInfo * info[10];
이렇게 바뀌어야 합니다... 수정하다가 주석이 잘못된 부분을 지우다 보니... ㅜㅜ
위에서 읽으시다가 혼란스러우셨다면 죄송합니다...
참고해보세요.
- scanf() 함수의 인자값. 리턴값. 오류값을 확인해봅니다. 정식 문서를 참고해보세요.
- strncpy() 함수는 정해진 갯수의 문자 '만 복사합니다.
- 소스 코드를 한줄 씩. 디버깅 해서. 출력해 봅니다.
- 문자열의 마지막을 0x00 이나 NULL 로 초기화 해줘야 문자열로 인식합니다.
- 잘 되는 책 예제소스를 그대로 해봅니다.
- numBook 갯수가 없네요.
//구글 검색
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[64]
https://stackoverflow.com/questions/19439525/format-s-expects-argument-of-type-char-but-argument-2-has-type-char/19439537
//문서 예제에서는 & 주소 없이. 배열을 그냥 사용하네요.
scanf()
http://www.cplusplus.com/reference/cstdio/scanf/
구름 IDE - 웹 가상 머신 - 컴파일 테스트
https://www.goorm.io/
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
bookInfo * info = NULL;
bookInfo * info = NULL;
이렇게 하시는게 맞습니다. malloc() 으로 공간을 할당하신 후
info[0] .. info[9] 이런식으로 하시면 되겠죠. strcpy(info[0].author, "test") 이런 식으로 하시면 될 겁니다.
댓글 달기