2014-04-21 2 views
0

이 코드 세그먼트가이 출력을 제공하는 이유는 무엇입니까? 나는 패킷 수를 늘려야한다. 수신기네트워크상의 C에서 형식 문자열 오류

while(1) { 
      if(argv[3]) { 
        strcpy(buf, argv[3]); 
      } else { 
        msg = "This is a UDP test string! (packet %d)\n", ++pktcnt; 
        strcpy(buf, msg); 
      } 

      ret = sendto(udpSocket, buf, strlen(buf)+1, 0, (struct sockaddr*)&udpServer, sizeof(udpServer)); 
      if(ret == -1) { 
        fprintf(stderr, "Could not send message!\n"); 
        return -1; 
      } else { 
        printf("Message sent. (packet %d)\n", pktcnt); 
      } 
      sleep(1); 
    } 

출력 :

This is a UDP test string! (packet %d) 
This is a UDP test string! (packet %d) 
This is a UDP test string! (packet %d) 

는 분명히 형식 문자열에 문제가있는 것입니다하지만 난 그것을 알아낼 질수 : | 이것은 단순한 오류라고 확신하지만 아직 C가 너무 많다는 것을 모릅니다. 이것은 파이썬에서도 작동합니다!

+3

'msg = "string", argument'는 당신이 생각하는대로하지 않습니다. 'sprintf'를 찾는다. (그리고, 가급적이면'snprintf'를 찾는다.) – usr2564301

답변

3
msg = "This is a UDP test string! (packet %d)\n", ++pktcnt 

같은 공백이 문자열에 할당됩니다. 예를

char msg[200]; 
sprintf(msg, "This is a UDP test string! (packet %d)\n", ++pktcnt); 

아니면 buf에 직접 넣을 수 있습니다 경우 :

sprintf(buf, "This is a UDP test string! (packet %d)\n", ++pktcnt); 

가정 당신이 충분한 공간을 가지고 있었다. C에서 기억 공간을 스스로 할당해야한다는 것을 잊지 마십시오. 함수는 그것을하지 않으며 메시지를 얻을 때까지 많은 세분화 오류를 얻습니다 ....

+0

완벽한, 감사합니다! – tozhan

1

당신은 buf

msg = "This is a UDP test string! (packet %d)\n", ++pktcnt; 
strcpy(buf, msg) 

당신이 sprintf와 같은 것을 사용하고 있던 것 같은데에 복사하기 전에 msg를 포맷,하지만 그것을 제거되지 않습니다?

시도 뭔가 당신이 sprintf를 사용할 필요가

C.

에 변수로 포맷 된 문자열을 넣어, 당신은 적절한 있는지 확인해야하는 방법없는 그

sprintf(msg, "This is a UDP test string! (packet %d)\n", ++pktcnt); 
2
msg = "This is a UDP test string! (packet %d)\n", ++pktcnt; 

위의 문장에서 lhs의 쉼표는 쉼표 연산자입니다. 모든 운영자 중에서 가장 낮은 우선 순위를가집니다. 첫 번째 피연산자를 계산 한 다음 두 번째 피연산자를 계산 한 다음 두 번째 피연산자의 계산 결과를 반환합니다. 첫 번째 피연산자와 두 번째 피연산자의 평가 사이에는 시퀀스 포인트가 있습니다. 따라서 명령문은

(msg = "This is a UDP test string! (packet %d)\n"), ++pktcnt; 
    |            | |  | 
    |________________________________________________| |_______| 
        |         | 
        |         | 
      assignment expression      prefix increment 

과 실질적으로 동일합니다. 명령문은 접두사 증가 연산자의 값으로 평가됩니다. 따라서, msg 항상 문자열의 형식을

"This is a UDP test string! (packet %d)\n" 

리터럴 문자열을 가리키는, 당신은 snprintf 기능을 사용해야합니다.

char buff[100+1]; // +1 for the terminating null byte 
msg = "This is a UDP test string! (packet %d)\n" 

// write at most sizeof(buff) = 101 bytes into the 
// buffer buff including the terminating null byte 
snprintf(buff, sizeof buff, msg, ++pkcnt); 
+1

+1 기존 문장이 정확히 무엇인지 (오, 쉼표 연산자)를 설명하고,'sprintf'의 사용법을 보여주기 위해서입니다. 물론'sprintf'보다 안전합니다. – Floris