무한으로 arg 받아서 넘기기...?

베리스타의 이미지

안녕하세요.
C로 소켓프로그램 짜고 있는데, 파라미터를 무한으로 주고 받고 싶습니다.

exex함수의 경우 아래처럼 썼는데 썼는데
int execl( const char * path , const char * arg , ...);

저도 이런걸 하고 싶은데 방법을 몰라 고수분께 질문합니다.

우선 아래처럼 3개만 받아오는것만 test로 해봤고
int sndTosrv(char *hostaddr, char *urladdr) { }

int main(int argc, char *argv[])
{
int nCnt;
if (argc !=3)
{
printf("Usage : SendHeader IP_Address \n");
exit(1);
}

nCnt = sndTosrv(argv[1], argv[2]);
}

위에것을 arg를 무한으로 주고 받고 싶습니다.

방법좀 알려주세요. :o

taeyeung의 이미지

#include <stdio.h>
#include <stdarg.h>

void log( char *format, ...)
{
	va_list ap;
	FILE   *fp = NULL;

	fp = fopen( "log.txt", "a");

	va_start( ap, format);

	vfprintf( fp, format, ap);
	fprintf( fp, "\n");

	fclose(fp);

	va_end(ap);
}

위 코드를 참고하세요

dataeng의 이미지

... 은 가변 인자 형식을 표현하기 위한 것입니다.

printf("%d%lu%s%p", 3, 345L,"122", 0x1234);에서 다양한 형식인자열을
처리하기 위한 방법입니다.

메모리가 무한이 아니기 때문에 무한 파라미터처리는 불가능합니다.

보통은 컴파일러에서 최대 인자열의 갯수를 제한하는 것으로 알고 있습니다.

또한 이것이 printf류의 함수 코드의 크기가 커지는 주된 이유이기도 합니다.

베리스타의 이미지

stdarg.h파일을 쓰셨던데 그런 헤더 파일은 어디 있는건가여?-_-;;

무한은 아니더라도 여라개 쓰고 싶은데..말이 무한이지 보통 가야 할 데이타는 아무리 많아도 10개 넘지 않아여= )

아직도 구현하는 법을 잘 모르겠어요.ㅠ.ㅜ

int sndTosrv(??????????????) { }

int main(int argc, char *argv[]) {
nCnt = sndTosrv(?????????????);
}

위에서

???????????부분을 머라고 써야 할지 알려주세요.ㅠ.,ㅜ(2군데)

하이요^^

cedar의 이미지

베리스타 wrote:

int sndTosrv(char *hostaddr, char *urladdr) { }

int main(int argc, char *argv[]) 
{
	int nCnt;
	if (argc !=3)
    	{         
		printf("Usage : SendHeader IP_Address \n");         
		exit(1);     
    	}
	
	nCnt = sndTosrv(argv[1], argv[2]);
}

위에것을 arg를 무한으로 주고 받고 싶습니다.

방법좀 알려주세요. :o

글쎄요... 이 경우에는 가변 인자를 쓰는 것 보다는, 차라리
sndTosrv 함수가 argc와 argv[]를 그대로 받는 게 낫지 않을지요?

int sndTosrv(char *hostaddr, char *urladdrs[], size_t n) 
{ 
  // 내부 처리는 알아서...  :) 
}

int main(int argc, char *argv[]) 
{
	int nCnt;
	if (argc  < 2)
    	{         
		puts("Usage: SendHeader IP_Address \n");         
		exit(1);     
    	}
	
	nCnt = sndTosrv(argv[1], &argv[2], argc - 1);
}
ageldama의 이미지

#include <stdio.h>
#include <stdarg.h>

int sndTosrv(char *host, ...)
{
	va_list ap;
	char *sz;

	va_start(ap, host);
	while( 1 ) {
		sz = va_arg(ap, char*); 
		if ( sz == NULL ) break;
		printf("[%s]\n", sz);
	} 
	va_end( ap ); 

	return 0;
}


int main(int argc, char *argv[])
{
	sndTosrv("foo", "bar", "zoo");

	return 0;
}

요기

...에 사용하실 인자가 같은 형이라면 단순하게 푸실 수 있을거 같은데요?
인자형이 다르다면 python의 pack()처럼 인자들 타입의 목록을 받으시면 되겠구요.

#include <stdio.h>
#include <stdarg.h>

//  Declaration, but not definition, of ShowVar.
int ShowVar( char *szTypes, ... );

void main()
{
    ShowVar( "fcsi", 32.4f, 'a', "Test string", 4 );
}
//  ShowVar takes a format string of the form
//   "ifcs", where each character specifies the
//   type of the argument in that position.
//
//  i = int
//  f = float
//  c = char
//  s = string (char *)
//
//  Following the format specification is a list
//   of n arguments, where n == strlen( szTypes ).
void ShowVar( char *szTypes, ... )
{
    va_list vl;
    int i;

    //  szTypes is the last argument specified; all
    //   others must be accessed using the variable-
    //   argument macros.
    va_start( vl, szTypes );

    // Step through the list.
    for( i = 0; szTypes[i] != '\0'; ++i )
    {
        union Printable_t
        {
            int     i;
            float   f;
            char    c;
            char   *s;
        } Printable;

        switch( szTypes[i] )    // Type to expect.
        {
        case 'i':
            Printable.i = va_arg( vl, int );
            printf( "%i\n", Printable.i );
            break;

        case 'f':
            Printable.f = va_arg( vl, float );
            printf( "%f\n", Printable.f );
            break;

        case 'c':
            Printable.c = va_arg( vl, char );
            printf( "%c\n", Printable.c );
            break;

        case 's':
            Printable.s = va_arg( vl, char * );
            printf( "%s\n", Printable.s );
            break;

        default:
            break;
        }
    }
    va_end( vl );
}

첫번째 코드조각은 허접하게 급조해 본건데 기이한 현상이 있더군요.
VC++7에서 테스트 해보았는데 Debug로 실행할때 빼고는 런타임에러를-_-

----
The future is here. It's just not widely distributed yet.
- William Gibson

sliver의 이미지

#include <stdio.h> 
#include <stdarg.h> 

int sndTosrv(char *host, ...) 
{ 
   va_list ap; 
   char *sz; 

   va_start(ap, host); 
   while( 1 ) { 
      sz = va_arg(ap, char*); 
      if ( sz == NULL ) break; 
      printf("[%s]\n", sz); 
   } 
   va_end( ap ); 

   return 0; 
} 


int main(int argc, char *argv[]) 
{ 
   sndTosrv("foo", "bar", "zoo"); 

   return 0; 
} 

Quote:

첫번째 코드조각은 허접하게 급조해 본건데 기이한 현상이 있더군요.
VC++7에서 테스트 해보았는데 Debug로 실행할때 빼고는 런타임에러를-_-

main에서 sndTosrv호출할때, 맨 마지막 인자로써 NULL을 넘겨줘야 잘 작동하겠네요.
베리스타의 이미지

여러 도움을 받은 덕에 이제 사회 초짜인 제가 사수가 내준 과제를 해냈습니다. :o

감사드려요^^

많은 도움 주신분들과 관심을 가지고 읽어주신분들께 감사드립니다.

위에 답변에 친절한 답변들이 자세히 나온 관계로 제 소스는 올리지 않습니다.

제가 한 작업은 소켓으로 php에 있는 헤더, 데이타부분 받는것인데 인증절차에서 각 api마다 서로 다른수의 파라미터가 나와서 arg를 가변적으로 여러개 받는것을 구현하고자 한것입니다.

모두들 즐프하시고. 이제 사회 초년생인관계로 열심히 여쭤보고 게시판도 읽어보고 할테니 많이 도와주세요^^;

그럼 Hav' a nice day

하이요^^

이한길의 이미지

그냥 배열로 받으면 되지 않나요?? 배열로 ...
그러면 제한되지 않은 갯수를 받을 수 있는데..

그리고.. 그렇지 않으면 포인터로.. 하긴 내부에서 처리는 같던가??
암튼 잘 모르겠지만 배열을 사용하심이...

----
먼저 알게 된 것을 알려주는 것은 즐거운 일이다!
http://hangulee.springnote.com
http://hangulee.egloos.com

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.