2015-12-27 50 views
-3

我正在製作一個程序,其目的之一就是它需要能夠根據字符將輸入分隔成不同的字符串。 例如,輸入後5秒程序崩潰?

game.Lighting被分離成「遊戲」和「照明」 game.Properties.Hey被分離成「遊戲」和「屬性」,「嘿」 基本上,它只是刪除了。並將它們分成不同的字符串。

然而,當我輸入我希望字符串是,它的工作原理以及它是否已完全正常,然後崩潰約5秒後出​​現錯誤「字符串str已損壞」

這是我的代碼。

#include "stdafx.h" 
#include <string.h> 
#include <iostream> 
#include <Windows.h> 

using namespace std; 
int main() 
{ 
    char str[2] = "."; 
cin >> str; 
char * pch; 
printf("Splitting string \"%s\" into tokens:\n", str); 
pch = strtok(str, "."); 
while (pch != NULL) 
{ 
    printf("Getting %s then ", pch); 
    pch = strtok(NULL, "."); 
} 
Sleep(5000); 
return 0; 
} 

我改變了char str [] =「。」以char str [2] =「。」

不過,我現在得到的錯誤(這是後該程序已編譯並運行,然後它崩潰)「字符串str已損壞」

+1

你忘了把你的照明放入軌道。 –

+1

什麼@LightnessRacesinOrbit – JStep

回答

4

str只保留空間,兩個字節"."char[2] 。對於任何長度超過一個字符的C字符串來說空間太小(由於空字節,「一」不是「兩」),因此可能會發生未定義的行爲。


您使用C++如此編寫相應的代碼! strtok是C. printf是C. char[]是C.反而使用C++設施!
定義std::string,然後讀入它使用std::cin

std::string str; 
std::cin >> str; 

strtok所述可以很容易地在很不錯的C來實現++與std::findstd::string::findstd::for_each,或一些類似的效用函數。

我想出了這個,希望不需要爲自己感到羞恥得太厲害:

std::size_t pos = 0, tmp; 
while ((tmp = str.find('.', pos)) != std::string::npos) { 
    str[tmp] = '\0'; 
    std::cout << "Getting " << str.substr(pos) << " then "; 
    pos = tmp; 
} 
std::cout << "Getting " << str.substr(pos) << " then "; 

由於C++ 11,我們有<chrono><thread>。好極了!使用這樣的事情,而不是這個醜陋的,不可移植Sleep

std::this_thread:sleep_for(std::chrono::milliseconds(5000)); 

在Windows編程並不自動意味着任何人都可以寫不可移植的代碼!

注意所有這些函數都可以在C++中使用,但不屬於正常的,編寫良好的C++(11)程序。

+0

仍然出現錯誤:u – JStep

+0

@JStep您的更改?請寫下你的問題。 – Downvoter

+0

加了吧,對不起 – JStep