2013-04-14 3 views
1

WiFi 신호 강도가 포함 된 변수를 얻으려고합니다. 나는()를 호출하는 시스템에이를 넣을 때 다음 명령 리턴 성공적으로 터미널에서C 프로그램에서 터미널 명령을 실행해도 예상대로 동작하지 않습니다.

iwconfig wlan0 |grep Signal| cut -d"=" -f3 |cut -d" " -f1 

반환 1백분의 74

을 실행하지만 때, 나는 다음과 같은 컴파일 오류가 발생합니다.

int main(){ 
system("iwconfig wlan0 |grep Signal| cut -d"=" -f3 |cut -d" " -f1"); 
return 0; 
} 

나는 컴파일하면 ...

$ C++ wifi.cc wifi.cc 그 : 기능에서 'INT 주() :

wifi.cc:8:59 : 오류 : 읽기 전용 위치 지정 ' "iwconfig $ _ [0] | grep 신호 | cut -d"'

wifi.cc:8:59 : 오류 : 'const char [16]'할당에 호환되지 않는 유형 ~ 'const char [34]'

모든 아이디어/제안 매우 감사드립니다.

+0

당신의 당신의 커맨드의 * 출력 *을 얻기 위해'popen'을 사용할 수도 있습니다; 여전히 명령 문자열을 이스케이프해야합니다. –

답변

5

문자열 리터럴에 이스케이프 처리되지 않은 인용 부호가 있기 때문입니다. 당신이 그들을 탈출해야합니다 당신의 잘못된 코드에

system("iwconfig wlan0 |grep Signal| cut -d\"=\" -f3 |cut -d\" \" -f1"); 

은 인용 부호는 다음과 같이 짝되고있다 : 당신이 볼 수 있듯이, 세 개의 문자열 리터럴가

system("iwconfig wlan0 |grep Signal| cut -d"=" -f3 |cut -d" " -f1"); 
    ^        ^^   ^^ ^
     └─────────────────1─────────────────┘ └──────2─────┘ └─3──┘ 

. 당신이 따옴표를 탈출 한 후, 지금까지의 C++에 관한 한 따옴표의 한 쌍있다 :

system("iwconfig wlan0 |grep Signal| cut -d\"=\" -f3 |cut -d\" \" -f1"); 
    ^               ^
     └──────────────────────────────1──────────────────────────────┘ 

(가) 인용 부호 (그들의 앞에 \있는 사람) 문자열의 단지 일부를 탈출했다.

그러나 터미널에서 명령은 일부 문자열의 일부가 아닙니다. 그것은 그 자체로 그냥 명령이며, 인용문과 같이 짝됩니다

iwconfig wlan0 |grep Signal| cut -d"=" -f3 |cut -d" " -f1 
           ^^   ^^ 
            └1┘   └2┘ 
+0

그랬습니다. 나는 터미널에서 작동하는 이유에 관해서도 여전히 머리를 긁적니다 ... 감사합니다! – loopifnil

+0

@newtoxcode 터미널에서 문자열 리터럴의 일부가 아니기 때문에. 따옴표는 이스케이프 할 필요가 없습니다. –

+0

@newtoxcode 제 편집을보세요. 그것을 더 분명하게해야합니다. –

1

당신은 탈출하는 데 필요한 "\"과 같이 :

system("iwconfig wlan0 |grep Signal| cut -d\"=\" -f3 |cut -d\" \" -f1"); 

그렇지 않으면 당신이 첫 번째 경우에있는 것은 :는 리터럴 문자열에 할당하려고

"iwconfig wlan0 |grep Signal| cut -d" = " -f3 |cut -d" 
            ^^^ 

여기서 오류 assignment of read-only location이 발생합니다.

+0

그랬습니다. 나는 터미널에서 작동하는 이유에 관해서도 여전히 머리를 긁적니다 ... 감사합니다! – loopifnil

0

당신은이 같은 문자열의 내부에 인용 부호를 추가 할 이스케이프 시퀀스를 사용해야합니다 :

system("iwconfig wlan0 |grep Signal| cut -d\"=\" -f3 |cut -d\" \" -f1"); 
//           ^^ ^^   ^^ ^^ 
+0

그랬습니다. 나는 터미널에서 작동하는 이유에 관해서도 여전히 머리를 긁적니다 ... 감사합니다! – loopifnil

1

문자열이 단순하고 이스케이프 - 지옥을 피하고 싶다면 셸 명령에서 작은 따옴표를 사용할 수도 있습니다.:

system("iwconfig wlan0 |grep Signal| cut -d'=' -f3 |cut -d' ' -f1"); 

이 유일한 작품 쉘에서 당신이 따옴표와 문자열 리터럴에 대한 작은 따옴표 (이 둘 사이 차이가 있지만, 지금 우리가 그들에 대해 걱정하지 말자)를 모두 사용할 수 있기 때문이다.

나는 터미널 프로그램을 실행하는 대신 라이브러리 호출을 사용하는 것이 좋습니다. 이것은 프로그램을 더 빨리 만들어야합니다 (라이브러리를 호출하여 외부에서 값을 얻고 인쇄하는 외부 프로그램을 호출 할 필요가 없으며 인쇄물을 구문 분석하고 올바른 값을 읽는 경우에만 유용합니다) 예를 들어, 만약 때문에 새 버전의 또는 단순히 다른 언어로 실행되고 있기 때문에 iwconfig 변화의 출력 또는 당신은

는 한 번 봐이) 여러 개의 무선 연결을 가지고, 또는 ...하는 libiw

관련 문제