注册 登录
编程论坛 C# 论坛

新手求助如果从文件里读入数据

xinqing928 发布于 2014-01-11 17:00, 1430 次点击
各位大侠,我的文件是这样的
417  25781 1800
 3600   2011  7  22  0  0
0.000    0.038     0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050
0.050    0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050
0.050    0.050     0.050     0.050     0.000     0.050     0.050     0.050     0.050     0.050
0.050    0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050
0.050    0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050     0.050
0.050    0.050     0.050     0.042     0.000     0.050     0.050     0.050     0.050     0.050....
用FORTRAN的话就这样读。
READ(10,*)NT,NP,DT
DO I =1,NT
        READ(10,*)K,IYR,IMN,IDA,IHR,IMI,RISEC
        READ(10,*) (ZZ(J),J=1,NP)
        READ(10,*) (UU(J),J=1,NP)
        READ(10,*) (VV(J),J=1,NP)
        READ(10,*) (SS(J),J=1,NP)
ENDDO
但是用C#怎么才能达到FORTRAN这样的赋值效果呢?百试不成功,求助。
27 回复
#2
xinqing9282014-01-11 20:22
自己顶一下,急求大侠们HELP
#3
TonyDeng2014-01-12 13:19
不動fortran,把你要怎樣的讀取效果用文字描述出來。
#4
xinqing9282014-01-12 14:25
以上面数据为例把417赋值给NT,25871赋值给NP,1800赋值给DT
第二行是时间。读完第二行后,然后把NP个数赋值给ZZ(),后NP个数赋值给UU(),再NP个数赋值给VV(),再NP个数赋值给SS(),然后再读第二个时间,如此循环。求版主,大侠们指点
#5
TonyDeng2014-01-12 14:29
你的DT沒用到,檢查一下寫清楚,而且看你的數字都是0.05,時間又不知是怎麽回事。
#6
xinqing9282014-01-12 14:50
DT是用到的,下个时间就是第一个时间+DT秒,不过这个我不关心,关心的就是怎么把这些数字读入到数组里。
            string path = @"D:\现状.fld";
            FileStream aFile = new FileStream(path, FileMode.OpenOrCreate);
            StreamReader sw = new StreamReader(aFile);
            string line = sw.ReadLine();
            string[] stringarray;
            stringarray = line.Split(new char[] { ' ' });这样读最方便吗?我这里不一定两个数间都只空一个空格
#7
TonyDeng2014-01-12 14:55
是的,用Split()最方便,拆分后,用trim()篩掉空格,若不需要字符串結果,直接把分割的子串轉換爲對應的數值即可(它會過濾空格)。
#8
xinqing9282014-01-12 14:57
那也就是只能按行读,不能像FORTRAN一样按个数读了
#9
TonyDeng2014-01-12 14:59
把從第3行開始的數據一次讀到字符串中,再用空格和回車(嚴格說不是回車,而是new_line符號)調用Split()。
#10
xinqing9282014-01-12 15:03
能否简单写几句代码?我太菜了,光说说实现版主思想,有点吃力
#11
TonyDeng2014-01-12 15:06
Split()後面的分隔符參數可以帶多個,你查一查幫助就知道。也就是說,用' '和new_line做分割,Split()會把用空格或用new_line分隔的子串都一視同仁地提取出來。
#12
TonyDeng2014-01-12 15:57
解決了嗎?
#13
TonyDeng2014-01-12 16:16
要麽你把數據文件發上來我試試
#14
xinqing9282014-01-12 21:55
只有本站会员才能查看附件,请 登录
这个是文件,再求版主指点。
#15
TonyDeng2014-01-13 11:00
你第2行最後那個浮點數是怎麽回事?
#16
xinqing9282014-01-13 11:12
表示的是秒。
#17
xinqing9282014-01-13 11:14
我的数据格式就是98个时间,每个时间要读Z,U,V,S四个数组,每个数组有333个数。然后下一时间就是这一时间的基础上加上1800S。再读下个时间的Z,U,V,S,不知道我说明白了吗?
#18
TonyDeng2014-01-13 11:15
整數之中夾雜浮點數,它在固定位置出現的嗎?
#19
TonyDeng2014-01-13 11:17
#20
TonyDeng2014-01-13 11:21
那數據文件是你自己生成的嗎?爲什麽後面的數據不是333個之後再回車換行?這樣憑空增加了負擔。
#21
xinqing9282014-01-13 11:40
数据是虽然不是自己生成的,但是可以用FORTRAN改为想要的格式,要是怎么样方便读的话,指教我一下如何修改吧
#22
TonyDeng2014-01-13 11:42
如果你不能改變文件佈局,照這樣做也是可以的。我中午要外出一下,先提示你一點關鍵的思路,若還搞不定,我晚上回來再改一下現在做好的。

關鍵點:你的數據都是定寬的!頭2行的整數,全部是7位寬,讀數據時按這個寬度讀,然後轉換就是了。浮點數都是10位寬的。

本來一批過讀333個(這數字從NP來)浮點數,是最方便的,但由於多了回車換行符的干擾,要先把它們過濾掉。
#23
xinqing9282014-01-13 14:29
版主还是贴一下吧,总能学习一下
#24
TonyDeng2014-01-13 21:40
我不給你全部做完,你自己參照這個路子改吧:

程序代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using namespace ConsoleApplication4
{
    class Program
    {
        static void Main(String[] args)
        {
            if (args.Count() == 0)
            {
                Console.WriteLine("請以數據文件名路徑作爲參數啓動程序!");
                return;
            }

            String fileName = args[0].Trim();
            if (!File.Exists(fileName))
            {
                Console.WriteLine("文件{0}不存在,請檢查并重新輸入。", fileName);
                return;
            }

            Int32 intWidth = 7;        // 整型數據的寬度
            Int32 floatWidth = 10;     // 浮點數據的寬度
            Int32 itemsInLine = 10;    // 每行的項數

            Int32 index;

            using (StreamReader file = File.OpenText(fileName))
            {
                Int32 NT = GetInteger(file, intWidth);
                Int32 NP = GetInteger(file, intWidth);
                Int32 DT = GetInteger(file, intWidth);
                file.ReadLine();
                Console.WriteLine("NT={0}, NP={1}, DT={2}", NT, NP, DT);
                for (index = 0; index < 6; ++index)
                {
                    Console.Write("{0},", GetInteger(file, intWidth));
                }
                Console.WriteLine("{0:F3}", GetFloat(file, floatWidth));
                file.ReadLine();
                Int32 counter = 0;
                List<Double> Z = new List<Double>();
                index = 0;
                while (index < NP)
                {
                    if (counter < itemsInLine)
                    {
                        Z.Add(GetFloat(file, floatWidth));
                        ++counter;
                        ++index;
                    }
                    else
                    {
                        file.ReadLine();
                        counter = 0;
                    }
                }
                foreach (Double data in Z)
                {
                    Console.Write("{0} ", data);
                }
                Console.WriteLine("\nZ[]的總項數={0}", Z.Count());
            }
        }

        static Int32 GetInteger(StreamReader file, Int32 width)
        {
            Char[] array = new Char[width];
            if (file.Read(array, 0, width) > 0)
            {
                return Int32.Parse(new String(array));
            }
            else
            {
                return 0;
            }
        }

        static Double GetFloat(StreamReader file, Int32 width)
        {
            Char[] array = new Char[width];
            if (file.Read(array, 0, width) > 0)
            {
                return Double.Parse(new String(array));
            }
            else
            {
                return 0.0;
            }
        }
    }
}


關鍵是那兩個函數,以及在適當時候讀走換行的手法。
#25
有容就大2014-01-13 22:33
来帮顶 学习下~~
#26
TonyDeng2014-01-13 22:37
以下是引用有容就大在2014-1-13 22:33:39的发言:

来帮顶 学习下~~

流竄犯,趕你回水區!
#27
有容就大2014-01-13 23:16
哈哈  冒个泡而已 不要这么大火气吧
#28
xinqing9282014-01-14 09:09
万分感谢版主的热心帮忙,已经散分结帖
1