最近玩Arduino發現,在編寫函數庫的時候要用到C++。正好手頭有一本教材,於是時隔2年,開始重學。
又看到重載、構造、拷貝這些詞竟然還有些小興奮。
開個系列日志記錄一下學習過程中的問題和體會。
看到輸入輸出的時候想到了C++對C的兼容性,於是試了一下printf函數。
1 # include<iostream> 2 # include<stdio.h> 3 using namespace std; 4 5 int main() 6 { 7 cout<<"C++ iostream"<<endl; 8 printf("C standard io"); 9 10 return 0; 11 }
果然還是不錯的。
可是又在StackOverFlow上發現了別人的問題。有人在嘗試用printf輸出string變量。
1 # include <iostream> 2 3 int main() 4 { 5 using namespace std; 6 7 string myString = "Press ENTER to quit program!"; 8 cout << "Come up and C++ me some time." << endl; 9 printf("Follow this command: %s", myString); 10 cin.get(); 11 12 return 0; 13 }
提問者說“Each time the program runs, myString
prints a seemingly random string of 3 characters...”
對這個問題,直接引用下面chris大神的回答。
It's compiling because printf
isn't type safe, since it uses variable arguments in the C sense. printf
has no option for std::string
, only a C-style string. Using something else in place of what it expects definitely won't give you the results you want. It's actually undefined behaviour, so anything at all could happen.
The easiest way to fix this, since you're using C++, is printing it normally with std::cout
, since std::string
supports that through operator overloading:
std::cout << "Follow this command: " << myString;
If, for some reason, you need to extract the C-style string, you can use the c_str()
method of std::string
to get a const char *
that is null-terminated. Using your example:
1 #include <iostream> 2 #include <string> 3 4 int main() 5 { 6 using namespace std; 7 8 string myString = "Press ENTER to quit program!"; 9 cout << "Come up and C++ me some time." << endl; 10 printf("Follow this command: %s", myString.c_str()); //note the use of c_str 11 cin.get(); 12 13 return 0; 14 }
If you want a function that is like printf
, but type safe, look into variadic templates (C++11, supported on all major compilers as of MSVC12). You can find an example of one here. There's nothing I know of implemented like that in the standard library, but there might be in Boost, specifically boost::format.
復制以上代碼,在geany下編譯的時候沒有成功,提示error: ‘printf’ was not declared in this scope,果然加上#include <stdio.h>後編譯成功。
由此可見,geany畢竟是一個輕量級的編程環境,main函數必須返回int之類的要求不知道是否是嚴謹性的體現。總之學習過程中用geany足矣,也希望能借此養成良好的編程習慣。