C언어 구조체 포인터로 멤버의 주소에 접근해서 scanf 혹은 strcpy 사용

익명 사용자의 이미지


안녕하세요! 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 * 배열로 인식하는 건지 선배님들의 가르침 부탁드립니다 ㅜㅜ

질문자의 이미지

bookInfo * info = NULL;

이 부분이
bookInfo * info[10];
이렇게 바뀌어야 합니다... 수정하다가 주석이 잘못된 부분을 지우다 보니... ㅜㅜ
위에서 읽으시다가 혼란스러우셨다면 죄송합니다...

shint의 이미지

- 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/

  char str [80];
  scanf ("%79s",str);  

구름 IDE - 웹 가상 머신 - 컴파일 테스트
https://www.goorm.io/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define debugmode 0
 
//구조체 정의
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[10];
	int numBook = 0, i = 0;
 
	numBook = 2;
//statements
    printf("How many books do you want to tag? put numbers: ");
 
	for(int i=0; i<10; i++)
	{
		info[i] = (bookInfo *)malloc(sizeof(bookInfo));
		memset(info[i], 0x00, sizeof(bookInfo));
	}
 
//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("Output book #%d\n", i+1);
        outputInfo(info[i]);
    }
 
	for(int i=0; i<10; i++)
	{
		free(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);
 
}

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

라스코니의 이미지

bookInfo * info = NULL;
이렇게 하시는게 맞습니다. malloc() 으로 공간을 할당하신 후
info[0] .. info[9] 이런식으로 하시면 되겠죠. strcpy(info[0].author, "test") 이런 식으로 하시면 될 겁니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.