這段C++代碼不能按照預期運行,請問錯在哪裡?
誰也不樂意照著圖片把作業代碼敲一遍的。所以只能人肉編譯器胡亂編譯運行一下了,產生任何「未定義行為」,均由題主解決,本人概不負責。
這代碼毛病挺多,不想一一說了,最主要的就是一個:z 字元串沒有初始化。z 裡面的內容是不確定的,而 strcat 要先找到 z 的尾巴,這個尾巴在哪裡,很不好說。這程序居然沒有立即崩潰不錯了,還要啥自行車。
你為什麼不把每個中間結果列印一下然後自己看呢?
首先知乎程序員本來就很多,其次知乎ers一向不提倡在知乎上求助作業,再者你的程序實在稱不上是C++:畢竟全程序只有cout勉強算得上是c++特性。因此被很多人噴想必也是情理之中吧。
不過我能理解。很多學校教的C++程序基礎都是披著皮的,基本都是C with cincout(甚至算不上C with STL)
第一次見到*strcat,請教一下,你這樣是想幹啥?
12/29答案有錯誤,修改。
主要有以下問題:
- z沒有初始化賦值0, char[a] = {0}。如果不初始化賦值0,則不知道這段內存里開始存的是什麼東西,後面的strcat很可能無法找到應該從哪裡開始放置字元。賦值為0,則會從最開始拷貝。
- *strcat這個不應該算漏洞吧,但沒必要這沒寫。strcat返回的是指向首字母的指針,採用*運算符得出的是首字母,但你並沒有使用,因此可以直接去掉*。
其實這段代碼並沒有使用很多的C++特性,如果題主的想法是定義兩個字元串併合並,然後一個一個輸出,可以看看C++新加入的一個類string,它有很多直接且安全的方法可以實現你要的功能。
這代碼看得我...,既然你寫的是C++,那我就說點問題好了
幾個問題
- 要不就全用C++,要不就全用C,不要混著用,看著怪難受的
- using namespace std 這種陋習就不要再寫了,多寫幾個std::死不了
- 請不要用&這種寫法,請使用&
- 列印C字元串請使用printf
- 你那兩個strcat前面加*是想幹嘛...
- 請直接在for語句裡面定義i,C++認為這是合法的
- sizeof函數返回的是size_t, 請不要寫這種含有隱式類型轉換的語句,請使用static_cast&(sizeof(xxx))
- x, y 是兩個常量的字元串,所以你的z才沒有報錯,這不是C,不存在用int來給數組開空間的可變數組,你這麼寫很奇怪,同時請初始化z,至少給它一個
這個問題的回答著實把我逗樂了,雖然在考試周,還是來花幾分鐘答一下,以防題主被知乎精英帶到知乎式編程上。
首先我假定題主是大一上期末,剛接觸編程。另外我沒用過vc,只用過vs,我假定這兩者在我所談到的方面是一致的。
題主這個代碼風格比較好,比我見的學了半年程設的多數人都強,縮進、大括弧一致,函數與頭文件之間的空行也注意到了,你別看某些答主說這代碼多爛多爛,他們自己寫出來的代碼很可能沒這麼漂亮。風格上如果說有啥需要注意的話,你兩次strcat中對於逗號處理的不一致是個問題,不過這是小問題,相信你沒用過格式化工具,那麼寫成這樣真的很不錯了。
再說你問的問題,前幾行代碼都是對的,問題是從strcat那裡開始的。確實如某些人所說,你的數組z沒初始化,但是幾乎沒人說到真正的問題,為什麼沒輸出云云,要知道字元串不初始化的經典後果是燙燙燙而不是空串。
雖然我現在在用手機,沒空跑你的程序,但是我和那些見不得圖的知乎精英有所差別,我傾向於在腦子裡跑,因為這就十來行的基本代碼,如果這東西還非要上機實戰,那要腦子幹什麼呢?
strcat(z, x)時會先試圖找到字元串z的結尾,再將x複製到後面。但是由於你的z沒初始化,所以裡面的值是未定義的,對vc來說這應該是0xcc,而找結尾要找到0,所以strcat找遍z都找不到0,於是它到z之外的空間去找(這些空間不歸你管,你也不應該訪問,更不應該修改),它早晚會找到一個0,然後往後面複製字元串x的內容——嘭!程序炸了。
此時由於你試圖修改非法內存,出現了運行時錯誤(Runtime Error)。如果你在調試的話,vc會有彈窗告訴你內存0x********發生了衝突,但如果你在「開始執行(不調試)」的話,那麼控制台會停滯幾秒鐘,然後出現「請按任意鍵繼續」(Press any key to continue)。
所以並不是什麼都沒有輸出,而是程序已經崩潰了(如果沒有崩潰的話,理應會輸出一堆「燙」再加正確答案的)。
改當然也很簡單,第一步初始化z,我建議你寫成z[a] = 「」;而不是其他人推薦的大括弧,用空串具有更強的可讀性。改這個還不夠,因為你cout時邊界用的sizeof(z)而非strlen(z),這是有問題的,可能不影響你看到的答案,但確實是bug。
另外你初始化x y時的大括弧是不必要的,加上它們會讓別人難以理解你的意思,strcat前的*同樣不必要。
#include &
#include &
using namespace std;
int main() {
string s1 = "you are nice";
string s2 = "yes";
string s3 = s1 + s2;
for (auto s : s3) {
cout &
這種寫法好麻煩……
明明
string a="you are nice";
string b="yes";
a+=b;
cout &就行了……
不錯了,至少會 return 0 了(逃
要是我有時間(aka. 閑的蛋疼)的話就給你寫個現代 C++ 的解法
兩個方法:
- char z[a] {""}; 即給z初始化一個空字元串
- 或者把第一個strcat 改成 strcpy
把 * 去掉,雖然留著不會報錯,但是你這邊是調用兩個函數,而不是想要對調用完的返回的指針取 *
另外,強烈建議使用string。 C++不推薦使用C-style的string
難道教材還是vc6的,vs都2019了。。。20年都快有了吧。。。
- char array z needs to be initialized for strcat to work properly
- to print a C-style string, use printf, preferably
- there is no point to dereference strcat since dereferencing should yield no side effect in this case
這都2020了,還有用VC6. 0的?
數組大小是不能改變
要不是你沒有按照預期學習
就是你老師沒有按照預期講課
如果你不是計算機專業的 建議棄坑
#define _CRT_SECURE_NO_WARNINGS
#include &
#include &
#include &
void main()
{
char x[20]="you are nice";
char y[]=" yes";
strcat(x,y);
printf("%s
",x);
}
補充:
1.質疑void main()這種寫法的同學,你的C語言老師就是摸魚的,會教出一水的廢材,趕快逃離
2.提問者是大一新生,布置作業應該全是C語言的,很多回答卻用C++的cout給答案,
本來初學者就蒙B,再整個對象,是讓提問者從入門到放棄的節奏
你的代碼沒錯只是寫法非常奇怪,char[]聲明編譯器會自動為空數組額外加個結束符。沒看見結果只是可能需要在命令行./exe的方式運行,或者換個編譯器。
我覺得是編譯器的問題,要不就是操作系統有bug。
建議換台電腦試試
少用sizeof,sizeof會使代碼變得醜陋。
推薦閱讀: