C# - 从文本文件中提取卫星两行元素

Posted

技术标签:

【中文标题】C# - 从文本文件中提取卫星两行元素【英文标题】:C# - Extracting satellite two line elements from a text file 【发布时间】:2014-11-07 03:18:53 【问题描述】:

我对 c# 和一般编程非常陌生,所以如果这没有意义,我深表歉意...... 我需要能够搜索文本框或组合框以读取包含许多卫星两行元素代码的记事本文件。 文本文件是这样设置的:

0 VANGUARD 1
1 00005U 58002B   14242.42781498  .00000028  00000-0  24556-4 0  2568
2 00005 034.2497 271.4959 1848458 183.2227 175.4750 10.84383299975339
0 TRANSIT 2A
1 00045U 60007A   14245.43855606  .00000265  00000-0  95096-4 0  2208
2 00045 066.6958 193.0879 0251338 053.7315 060.2264 14.33038972819563
0 EXPLORER 11
1 00107U 61013A   14245.36883128  .00001088  00000-0  12832-3 0  1217
2 00107 028.7916 229.2883 0562255 219.9933 302.0575 14.05099145667434

等等

我需要在该框中搜索唯一卫星的名称(“第一”行中 0 之后的名称)并将该名称提取到另一个文本框中,并在我的代码中使用。此外,我需要单独提取框中所选名称正下方的 2 行代码(也用于代码中)。

我已经编写了代码来使用这两个线元素,但我无法自动将它们放入我的代码中。

谢谢

【问题讨论】:

为什么你不能只使用 split 方法.. 然后从那里你可以检查分割线 data.lenth 是否小于最长线的长度,似乎每 3 次行它以 ) 开头,然后命名..这实际上非常简单.. 你可以一次阅读所有文本并拆分该信息为你编码这个..? 我不太确定 split 方法是什么...我想自己尝试编写代码,但我不知道从哪里开始。我也忘了说我在搜索名字时需要忽略 0 如果你想写程序,你需要精益求精。以下是您需要使用(并阅读)的方法和其他项目:Using System.IO; File.ReadAllLines(); Split(); Arrays.. And, if you are feeling strong Regular Expressions ie RegEx 我给你留下了一个几乎完全编码的例子,你可以以此为基础,使用调试器并逐步检查代码以查看是否需要检查任何其他条件..谢谢 【参考方案1】:

这是我想出的你可以快速尝试的东西。

首先将文件放在本地硬盘上的文件夹中。

第二个我定义了文件路径的地方,用你的实际文件路径替换它,并知道如何使用@符号以及它在 C# 中的含义

第三个注意我如何使用字符串 .Replace 方法.. 你将不得不调整它我只是给你一个想法我不会为你编写整个代码.. 祝你好运。

static void Main(string[] args)

    var fileName = string.Empty;
    var filePath = @"C:\Users\myfolder\Documents\RGReports\"; //for testing purposes only 
    List<string> listNames = new List<string>();
    string[] filePaths = Directory.GetFiles(@filePath);
    foreach (string file in filePaths)
    
        if (file.Contains(".txt"))
        
            fileName = file;
            using (StreamReader sr = File.OpenText(fileName))
            
                //string s = String.Empty;
                var tempFile = sr.ReadToEnd();
                var splitFile = tempFile.Split(new string[]  "\r\n", "\n" , StringSplitOptions.None);
                foreach (string str in splitFile)
                
                    if (str.Length == 12)
                    
                        listNames.Add(str.Substring(0, str.Length).Replace("0", "").Replace("1", "").Replace("2A",""));
                    
                    Console.WriteLine(str);
                
            
        
    

结果将产生以下名称,例如在控制台应用程序中测试的名称

先锋

过境

探索者

【讨论】:

【参考方案2】:

您可以使用regular expressions 完成此任务。

(我假设名称后面的字母/数字块也是名称的一部分)

此代码将执行以下操作:

将卫星名称和两行捕获到Satellite对象中 使用卫星名称填充 ComboBox 只要您选择了一颗卫星,您就可以知道它是哪一颗 一个搜索框,用于搜索以输入文本开头的第一颗卫星

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace WindowsFormsApplication3

    public partial class Form1 : Form
    
        private readonly BindingList<Satellite> _satellites = new BindingList<Satellite>();
        private string _input = @"
0 VANGUARD 1
1 00005U 58002B   14242.42781498  .00000028  00000-0  24556-4 0  2568
2 00005 034.2497 271.4959 1848458 183.2227 175.4750 10.84383299975339
0 TRANSIT 2A
1 00045U 60007A   14245.43855606  .00000265  00000-0  95096-4 0  2208
2 00045 066.6958 193.0879 0251338 053.7315 060.2264 14.33038972819563
0 EXPLORER 11
1 00107U 61013A   14245.36883128  .00001088  00000-0  12832-3 0  1217
2 00107 028.7916 229.2883 0562255 219.9933 302.0575 14.05099145667434
";

        public Form1()
        
            InitializeComponent();
        

        private void Form1_Load(object sender, EventArgs e)
        
            var regexObj =
                new Regex(@"(?<=^\d+\s(?<name>[\w|\d|\s]+))\r\n(?<line1>(?<=^).*)\r\n(?<line2>(?<=^).*(?=\r))",
                    RegexOptions.Multiline);
            Match matchResult = regexObj.Match(_input);

            while (matchResult.Success)
            
                string name = matchResult.Groups["name"].Value;
                string line1 = matchResult.Groups["line1"].Value;
                string line2 = matchResult.Groups["line2"].Value;


                var regexObj1 = new Regex(@"(?<=^[1|2].*)([\d\w.-]+)");
                Match matchResult1 = regexObj1.Match(line1);
                var numbers1 = new List<string>();
                while (matchResult1.Success)
                
                    string s = matchResult1.Value;
                    numbers1.Add(s);
                    matchResult1 = matchResult1.NextMatch();
                

                var regexObj2 = new Regex(@"(?<=^[1|2].*)([\d\w.-]+)");
                Match matchResult2 = regexObj2.Match(line2);
                var numbers2 = new List<string>();
                while (matchResult2.Success)
                
                    string s = matchResult2.Value;
                    numbers2.Add(s);
                    matchResult2 = matchResult2.NextMatch();
                

                _satellites.Add(new Satellite
                
                    Name = name,
                    Line1 = line1,
                    Line2 = line2,
                    Numbers1 = numbers1,
                    Numbers2 = numbers2
                );


                matchResult = matchResult.NextMatch();
            

            comboBox1.DataSource = _satellites;
            comboBox1.DisplayMember = "Name";
        

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        
            var comboBox = (ComboBox) sender;
            var satellites = comboBox.DataSource as List<Satellite>;
            if (satellites != null && comboBox.SelectedIndex > -1)
            
                Satellite selectedSatellite = satellites[comboBox.SelectedIndex];
                Console.WriteLine("Selected satellite: " + selectedSatellite.Name);
            
        

        private void textBox1_TextChanged(object sender, EventArgs e)
        
            var textBox = (TextBox) sender;
            string text = textBox.Text;
            if (!string.IsNullOrWhiteSpace(text))
            
                Satellite satellite =
                    _satellites.FirstOrDefault((s => s.Name.ToLower().StartsWith(text.ToLower())));
                if (satellite != null)
                
                    Console.WriteLine("Found satellite: " + satellite);
                
            
        

        private void textBox2_TextChanged(object sender, EventArgs e)
        
            var textBox = (TextBox) sender;
            string text = textBox.Text;
            if (!string.IsNullOrWhiteSpace(text))
            
                Satellite satellite =
                    _satellites.FirstOrDefault(
                        s => s.Numbers1.Any(t => t.StartsWith(text)) || s.Numbers2.Any(t => t.StartsWith(text)));
                if (satellite != null)
                
                    Console.WriteLine("Found satellite: " + satellite);
                
            
        
    

    internal class Satellite
    
        public string Name  get; set; 
        public string Line1  get; set; 
        public string Line2  get; set; 
        public List<string> Numbers1  get; set; 
        public List<string> Numbers2  get; set; 

        public override string ToString()
        
            return string.Format("Name: 0", Name);
        
    

结果:

【讨论】:

这太棒了,谢谢。但是我如何将它与组合框结合起来呢?我可以将组合框链接到文本文件,但我只需要卫星的 3 条单独的行作为输出 我已经更新了代码以捕获名称和两行,关于您的评论,您能解释一下您需要什么吗? 我希望这是有道理的......但它是用于卫星定位程序的。我使用卫星下方的两个线元素代码来查找卫星的坐标以及它与基准位置的关系(我的 GPS 坐标)。我有窗口窗体应用程序输出单个卫星的坐标、方位角和仰角等。我想要一个能够搜索卫星名称和元素数据库的文本框。选择卫星名称后,该名称下方的 2 行数字将显示在单独的文本框中,然后我可以将其放入我的代码中。 查看我的新代码!我会让你做剩下的,应该很简单:D 您好,我已将 3 个示例卫星链接到组合框,当从名称列表中选择特定卫星时,它会输出正确的元素。但我无法将更多卫星添加到此列表(例如,0 ISS(Zarya),1 25544U 98067A 14245.51991314 .00013026 00000-013431-3 0 101,2 25544 051.6451 076.2836 0003709 072.7397 020.6341 15.50183561903328),也可以获取代码以在文本文件中搜索这些元素。【参考方案3】:

如果你不想使用正则表达式,你可以这样做:

public List<string> GetSatelliteNames(string input)

    string[] split = input.split(new string[2]  "\n", "\r\n" );
    List<string> result = new List<string>();    
    foreach (var s in split)
    
        string splitagain = s.split(new char[1]  ' ' );
        if (s[0] == "0") result.add(s[1]);
    
    return result;

【讨论】:

以上是关于C# - 从文本文件中提取卫星两行元素的主要内容,如果未能解决你的问题,请参考以下文章

如何从包装的文本单元格中提取特定的文本行?

QT中怎样读取中文文本文件!

我的位图文本文件中的所有字符都是中文

C语言如何判断文本文档的结束

读取一行文本文件,拆分为数组

delphi写多行文本文件操作