有代码一百行,求简化
代码在上面,这个程序的目的是识别储存于文件中的命令并作出反应。
如你所见,这上面的代码实在有些臃肿,所用的方法简直可以用小儿科来形容。
我希望能用一种更简洁且执行效率更高的写法取代原来的代码,最好还能够放宽原有的限制条件(如“实际数值不管有多少位,始终只能占特定字符数,其他位没有就拿空格堆”这一问题)。
(我找到的这都什么破资料…)
本帖最后由 drzzm32 于 2015-7-10 18:36 编辑
额其实。。。字符串处理用.NET更方便呢。。。虽然我也不清楚你的定义是怎样的。。。
看看我的吧,从VB.NET翻译到C#的public static Scene[] LoadScript(string Path)
{
Scene[] Scenes;
int SceneIndexTmp;
int CGIndexTmp;
int ChoiceAutoIndexTmp;
string FullPath = Environment.CurrentDirectory + "\\" + Path;
IO.StreamReader Reader;
try {
Reader = new IO.StreamReader(FullPath);
} catch (Exception ex) {
Message MsgBox = new Message();
MsgBox.MsgShow("Error", "Config file contains error.");
MsgBox.Close();
return null;
}
string[] TmpString;
int TmpHead;
// ERROR: Not supported in C#: ReDimStatement
while (!Reader.EndOfStream) {
TmpString = Reader.ReadLine.Split({
Convert.ToChar(Space(1)),
Convert.ToChar(vbCr),
Convert.ToChar(vbTab)
});
TmpHead = 0;
try {
while (TmpString(TmpHead) == "") {
TmpHead += 1;
}
} catch (Exception ex) {
goto Bottom;
}
switch (TmpString(TmpHead)) {
case "开始定义场景":
case "defsc":
case "def.scene":
SceneIndexTmp = Convert.ToInt32(TmpString(TmpHead + 1));
Scenes(SceneIndexTmp) = new Scene();
Scenes(SceneIndexTmp).SceneIndex = SceneIndexTmp;
break;
case "结束定义场景":
case "endsc":
case "end.scene":
SceneIndexTmp = -1;
break;
case "背景":
case "backg":
case "set.back":
Scenes(SceneIndexTmp).BG.Path = TmpString(TmpHead + 1);
Scenes(SceneIndexTmp).BG.Index = SceneIndexTmp;
break;
case "音乐":
case "music":
case "set.bgm":
Scenes(SceneIndexTmp).BGM.Path = TmpString(TmpHead + 1);
break;
case "开始定义立绘":
case "defcg":
case "def.cg":
CGIndexTmp = Convert.ToInt32(TmpString(TmpHead + 1));
Scenes(SceneIndexTmp).CG(CGIndexTmp).IMG.Index = CGIndexTmp;
break;
case "结束定义立绘":
case "endcg":
case "end.cg":
CGIndexTmp = -1;
break;
case "立绘地址":
case "cgloc":
case "set.path":
Scenes(SceneIndexTmp).CG(CGIndexTmp).IMG.Path = TmpString(TmpHead + 1);
break;
case "立绘位置":
case "cgpos":
case "set.pos":
Scenes(SceneIndexTmp).CG(CGIndexTmp).Location = Convert.ToSingle(TmpString(TmpHead + 1));
break;
case "开始定义文字":
case "defwd":
case "def.word":
ChoiceAutoIndexTmp = 0;
switch (TmpString(TmpHead + 1)) {
case "对话":
case "comm":
case "type.comm":
Scenes(SceneIndexTmp).WordType = WordType.Comment;
break;
case "读档":
case "read":
case "type.read":
Scenes(SceneIndexTmp).WordType = WordType.Loading;
break;
case "存档":
case "save":
case "type.save":
Scenes(SceneIndexTmp).WordType = WordType.Saving;
break;
case "旁白":
case "scpt":
case "type.script":
Scenes(SceneIndexTmp).WordType = WordType.Script;
break;
case "标题":
case "titl":
case "type.title":
Scenes(SceneIndexTmp).WordType = WordType.Title;
break;
case "启动":
case "stup":
case "type.start":
Scenes(SceneIndexTmp).WordType = WordType.GameRun;
break;
}
break;
case "选择":
case "cword":
case "set.word":
for (i = TmpHead + 1; i <= TmpString.Length - 1; i++) {
if (i < TmpString.Length - 1) {
Scenes(SceneIndexTmp).Choices(ChoiceAutoIndexTmp).Context += TmpString(i) + " ";
} else {
Scenes(SceneIndexTmp).Choices(ChoiceAutoIndexTmp).Context += TmpString(i);
}
}
break;
case "跳转":
case "jmpto":
case "set.jump":
Scenes(SceneIndexTmp).Choices(ChoiceAutoIndexTmp).JumpSceneIndex = Convert.ToInt32(TmpString(TmpHead + 1));
ChoiceAutoIndexTmp = ChoiceAutoIndexTmp + 1;
break;
case "结束定义文字":
case "endwd":
case "end.word":
ChoiceAutoIndexTmp = -1;
break;
}
Bottom:
}
Reader.Dispose();
return Scenes;
}
核心是String.Split,按指定分隔符切分字符串。如果真做还要去学习编译原理(
本帖最后由 漆黑之翼 于 2015-7-10 20:04 编辑
我记得ifstream跟cin一样可以直接读成对应类型的啊,何必搞这么麻烦呢
我觉得还好...特别是在文件内容格式没有明显规律的情况下
如果要优化,那就是建立诸如读到空格即跳过,非空格则处理的策略了
另外不识别的指令直接用getline跳过去就好了,没必要一个个去偏移...
页:
[1]