TheRebirth 发表于 2015-7-10 15:40:03

有代码一百行,求简化



代码在上面,这个程序的目的是识别储存于文件中的命令并作出反应。
如你所见,这上面的代码实在有些臃肿,所用的方法简直可以用小儿科来形容。
我希望能用一种更简洁且执行效率更高的写法取代原来的代码,最好还能够放宽原有的限制条件(如“实际数值不管有多少位,始终只能占特定字符数,其他位没有就拿空格堆”这一问题)。

(我找到的这都什么破资料…)

drzzm32 发表于 2015-7-10 18:34:25

本帖最后由 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 19:35:03

本帖最后由 漆黑之翼 于 2015-7-10 20:04 编辑

我记得ifstream跟cin一样可以直接读成对应类型的啊,何必搞这么麻烦呢

fancydz 发表于 2015-7-13 11:48:59

我觉得还好...特别是在文件内容格式没有明显规律的情况下
如果要优化,那就是建立诸如读到空格即跳过,非空格则处理的策略了
另外不识别的指令直接用getline跳过去就好了,没必要一个个去偏移...

解放军 发表于 2015-7-19 11:40:10

页: [1]
查看完整版本: 有代码一百行,求简化