【问题标题】:dictionary error item with the same key has already been added已添加具有相同键的字典错误项
【发布时间】:2018-03-23 04:35:49
【问题描述】:

我正在尝试读取 C++ 标头中的每个 #define,并为每个值显示一个编辑器,以便我可以快速重新定义常量。

我正在尝试解析文件,让左侧的每个项目成为关键。我想在左侧显示值,编辑值并保存回来。目前,当我保存文件时,它会弄乱格式。

这是我目前拥有的代码:

private String header;
private Dictionary<String, String> tokens;
private String file = Properties.Settings.Default.path_location;
public TextBox elf_naparm_zombie_developer;

public harrs_gsh_editor(string file)//TextBox elf_naparm_zombie_developer
{
    Properties.Settings.Default.path_location = file;
    Properties.Settings.Default.Save();
    loadweapon();
   // this.elf_naparm_zombie_developer = elf_naparm_zombie_developer;
}

public void loadweapon()
{
    this.tokens = File.ReadLines(this.file)
        .Select(line => Regex.Match(line, @"^\s*#define\s+(.+?)(\s+(.+?))?((\s*//)|$)"))
        .Where(m => m.Success && m.Groups[3].Success)
        .ToDictionary(m => m.Groups[1].Value, m => m.Groups[3].Value);
}

public String Search(String name)
{
    foreach (KeyValuePair<String, String> pair in tokens)
    {
        if (pair.Key == name)
            return pair.Value;
    }

    return null;
}

public void Set(String key, String val)
{
    tokens[key] = val;
}

public void Save(String file)
{
    using (StreamWriter sw = new StreamWriter(File.OpenWrite(file)))
    {
        sw.Write(header);
        foreach (KeyValuePair<String, String> pair in tokens)
        {
            sw.Write("\r\n" + pair.Key + "#define       " + pair.Value);
        }
    }
}

public void Save()
{
    this.Save(file);
}

我遇到的问题是,当我将其保存回来时,它会弄乱文件并删除#define。我想要做的只是更改值并将其写回具有更改值的程序

这是file i want to edit

所以我想要做的是加载选定的键并显示我设法用我创建的这段代码做的值,但我遇到的问题是将它写回来

我用来加载和填充文本框的代码

namespace Harry_s_Template_Editor

{

public partial class Form1 : Form
{

    harrs_gsh_editor elfghc;
    string path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"/hb21_zm_ai_napalm.gsh";



    public Form1()
    {
        InitializeComponent();
        elfghc = new harrs_gsh_editor(path);//TextBox elf_naparm_zombie_developer
        elf_naparm_zombie_developer = elf_naparm_zombie_developer;
       // MessageBox.Show(path);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        elfghc.loadweapon();
        this.elf_naparm_zombie_developer.Text = elfghc.Search("NAPALM_ZOMBIE_DEVELOPER_DEBUG_PRINTS");
        elfghc.Set("NAPALM_ZOMBIE_DEVELOPER_DEBUG_PRINTS", elf_naparm_zombie_developer.Text);

    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button2_Click(object sender, EventArgs e)
    {
        elfghc.Set("NAPALM_ZOMBIE_DEVELOPER_DEBUG_PRINTS", elf_naparm_zombie_developer.Text);
        elfghc.Save(path);
    }
}

}

当我保存文件时,当我尝试再次加载程序时出现此错误 error

提前感谢由纪

file when saved back

【问题讨论】:

  • 您还缺少上面代码的类定义,请您补充一下吗?哪怕只是代码顶部的public class Form1 : Form,看看还是有帮助的
  • 为什么要按这个顺序写回文件:sw.Write("\r\n" + pair.Key + "#define " + pair.Value);#define 不应该在\r\n 之后排在第一位吗?我原以为应该是这样的:sw.Write("\r\n#define " + pair.Key + " " + pair.Value);
  • 是的,它设法解决了我遇到的唯一问题,尽管它删除了所有学分和类似的东西并破坏了它的所有格式,这里是写回它pastebin.com/sR8cVHgn,你可以看到另一个它删除了所有学分并删除了所有开始的东西
  • 我建议切换到 xml 文件。这允许拥有不同的类别,并且 .net 已经有用于阅读和编辑它们的库。也许最好的部分是,标题信息将位于一个单独的元素中,并且在您编辑其他部分时可以保持不变。另一个优点是,通过将设置放在一个类中,您可以直接从 xml 反序列化它们。

标签: c# dictionary key-value


【解决方案1】:

原答案:

为什么要按以下顺序将其写回文件:sw.Write("\r\n" + pair.Key + "#define " + pair.Value);#define 不应该在\r\n 之后排在第一位吗?我原以为应该是这样的:sw.Write("\r\n#define " + pair.Key + " " + pair.Value);

新答案(问题已更改)

你所做的有两个问题:

  1. 您正在将键/值对写回文件,而忽略了原始文件中的标题和信用。如果你很乐意把它们去掉,那很好,但听起来这对你很重要。因此,您需要读取文件,找到文件中的键,然后更新值并将更新的文件保存回磁盘。这是一个比简单地将一堆键/值对写入文件更难的问题。

  2. 第二个问题是您将文件写回磁盘的方式。根据this MSDN 页面,File.OpenWrite 具有以下行为:

如果文件已经存在,OpenWrite 方法会打开一个文件 路径,如果不存在则创建一个新文件。对于现有的 文件,它不会将新文本附加到现有文本。反而, 它用新字符覆盖现有字符。如果你 覆盖更长的字符串(例如“This is a test of the OpenWrite 方法”)使用较短的字符串(例如“第二次运行”),文件将 包含字符串的混合(“OpenWrite 的第二次运行测试 方法”)。

所以这就是为什么你会得到一个损坏的文件。您正在用更新的键/值对覆盖前 N 个字节,文件的其余部分是原始文件中的重复数据。您可能想改用以下内容,这将完全覆盖原始文件:

using (StreamWriter sw = new StreamWriter(file, false))

【讨论】:

  • 请注意,我并没有详细说明搜索和替换的“更难的问题”——但是您可以在很多现有的地方寻求帮助。我只是在回答“为什么会这样?”的问题
  • 感谢您的快速回复 我遇到的唯一问题是我对解析文件非常陌生将 file.openwright 更改为 file.writealltext 但错误说需要一个参数
  • 查看我的更新 - 最后一行。改用这个,抱歉,最后的建议有点混乱
  • 非常感谢您解决了这个问题 :) 积分和这无关紧要,因为如果用户使用我的程序,他们不会看到他们,所以非常感谢您标记为答案并投票支持的所有帮助
  • 谢谢!很高兴我能帮忙:)
猜你喜欢
  • 2013-03-18
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-11
相关资源
最近更新 更多