话题:学习交流C#读取本文文件中内容出错

.Net技术 码拜 7年前 (2017-04-28) 1151次浏览
       本人本人在学习C#时,遇到一个练习题:把csv文件中的联系人姓名和电话显示出来。简单模拟csv文件,csv文件就是使用”,”分割数据的文本,输出:姓名:张三  电话:15001111113 。它的意思就是将在bin\Debug目录下一文本文件”salary.txt”中的信息读取出来,之后按照它给定的格式在控制台上输出。
按照图片1所示的文本中的内容,在编辑器运行代码段一时,程序能够正常运行。嗯,在按照图片2所示的文本中的内容,本人将代码段一修改为代码段二后,程序运行会报“输入字符串的格式不正确”的错误。本人不知道该怎么样解决,求指点,谢谢。
对于代码一,其主要功能是读取文本内容中的每一行,之后使用Split()方法分割每个字符串,将“=”移除。对于代码二,由于在第2张图片中,其比图片1中的每行文本多了两个空格、一个“;”。本人通过修改代码段一,想在代码段二中能够将图片二所示的文本给切割,在控制台上输出同代码段一同样的格式。每次编译生成代码段二,编译成功。但是在程序运行时, 一直会报“输入字符串的格式不正确”的错误。本人不知怎么样解决,求指点,谢谢。

话题:学习交流C#读取本文文件中内容出错
图片1
话题:学习交流C#读取本文文件中内容出错
图片2
话题:学习交流C#读取本文文件中内容出错
图片3

代码段一

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test_160916_003
{
    class Program
    {
        static void Main(string[] args)
        {
          
            string[] lines = File.ReadAllLines("salary.txt", Encoding.Default);
            //假设第一个人的工资即为最高工资,也为最低工资。
            double max = double.Parse( lines[0].Split("=")[1] );
            double min = double.Parse(lines[0].Split("=")[1]);
            double sum = 0;
            double count = 0;
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines.Length != 0)
                {
                    count++;
                    double money = double.Parse(lines[i].Split("=")[1]);
                    sum += money;
                    if (max < money)
                    {
                        max = money;
                    }
                    if (min > money)
                    {
                        min = money;
                    }
                }  //if(lines[i].Length != 0)
                
            }
            Console.WriteLine("最高工资为{0}", max);
            Console.WriteLine("最低工资为{0}", min);
            Console.WriteLine("平均工资为{0}", (sum / count) );
            Console.ReadKey();
        }
    }
} 

代码段二

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test_160916_003
{
    class Program
    {
        static void Main(string[] args)
        {
          
            string[] lines = File.ReadAllLines("salary.txt", Encoding.Default);
            //假设第一个人的工资即为最高工资,也为最低工资。
            double max = double.Parse(lines[0].Split(new char[] { "=", "  ", ";" })[1]);    //修改的代码
            double min = double.Parse(lines[0].Split(new char[] { "=", "  ", ";" })[1]);    //修改的代码
            double sum = 0;
            double count = 0;
            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Length != 0)
                {
                    count++;
                    double money = double.Parse(lines[i].Split(new char[] { "=", "  ", ";" })[1]);    //修改的代码
                    sum += money;
                    if (max < money)
                    {
                        max = money;
                    }
                    if (min > money)
                    {
                        min = money;
                    }
                }  //if(lines[i].Length != 0)
                
            }
            Console.WriteLine("最高工资为{0}", max);
            Console.WriteLine("最低工资为{0}", min);
            Console.WriteLine("平均工资为{0}", (sum / count) );
            Console.ReadKey();
        }
    }
}

 [i] 在最后分享一首本人喜欢的词

孤雁儿·世人作梅诗
李清照 [宋]
藤床纸帐朝眠起。说不尽、无佳思。
沈香断续玉炉寒,伴本人情怀如水。
笛声三弄,梅心惊破,多少春情意。
小风疏雨萧萧地。又催下、千行泪。
吹箫人去玉楼空,肠断与谁同倚。
一枝折得,人间天上,没个人堪寄。

  本人美丽的校园

话题:学习交流C#读取本文文件中内容出错
解决方案

3

仅供参考:

//NAME: essaie bla bla
//DIMENSION: 8
//DATA
//1  14  15
//2  11  10
//3  6   4
//4  7   13
//5  9   21
//6  19  3
//7  1   5
//8  8   8
//EOF
//
// 文本文件中可能还含有其他内容,但是需要用到的内容即以上
//例如data.txt:
//NAME: essaie bla bla
//其它内容
//DIMENSION: 8
//其它内容
//DATA
//其它内容
//1  14  15
//其它内容
//2  11  10
//其它内容
//3  6   4
//其它内容
//4  7   13
//其它内容
//5  9   21
//其它内容
//6  19  3
//其它内容
//7  1   5
//其它内容
//8  8   8
//其它内容
//EOF
// 目标是要获取NAME后字串,DIMENSION后数值,以及DATA以下的数值
// 其中NAME就是随便个字句,DIMENSION是城市数量,DATA以下是城市编号,X坐标,Y坐标
// 全部的这些将赋值给一个事先定义好的结构
#include <stdio.h>
#include <string.h>
#define MAXCPL   80   //每行最大字符数
#define MAXCITY  100  //每组数据中DATA最多项数,DIMENSION的最大值
#define MAXNAMEL 32   //NAME最大长度
struct S {
    char NAME[MAXNAMEL+1];
    int  DIMENSION;
    struct D {
        int NO;
        int X;
        int Y;
    } DATA[MAXCITY];
} s;
FILE *f;
int st,n,i;
char ln[MAXCPL];
int main() {
    f=fopen("data.txt","r");
    if (NULL==f) {
        printf("Can not open file data.txt!\n");
        return 1;
    }
    st=0;
    n=0;
    while (1) {
        if (NULL==fgets(ln,MAXCPL,f)) break;
        if (st==0) {
            if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;
        } else if (st==1) {
            if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;
        } else if (st==2) {
            if (0==strcmp(ln,"DATA\n")) st=3;
        } else if (st==3) {
            if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {
                n++;
                if (n>=MAXCITY || n>=s.DIMENSION) break;
            }
        }
    }
    fclose(f);
    printf("s.NAME=[%s]\n",s.NAME);
    printf("s.DIMENSION=%d\n",s.DIMENSION);
    for (i=0;i<n;i++) {
        printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);
    }
    return 0;
}
//s.NAME=[essaie bla bla]
//s.DIMENSION=8
//s.DATA[0].NO,X,Y=1,14,15
//s.DATA[1].NO,X,Y=2,11,10
//s.DATA[2].NO,X,Y=3,6,4
//s.DATA[3].NO,X,Y=4,7,13
//s.DATA[4].NO,X,Y=5,9,21
//s.DATA[5].NO,X,Y=6,19,3
//s.DATA[6].NO,X,Y=7,1,5
//s.DATA[7].NO,X,Y=8,8,8

再供参考:

#include <stdio.h>
#include <string.h>
char string[80];
char seps1[3];
char seps2[3];
char *token;
char *zzstrtok (
    char *string,
    const char *control1,//连续出现时视为中间夹空token
    const char *control2 //连续出现时视为中间无空token
    )
{
    unsigned char *str;
    const unsigned char *ctrl1 = (const unsigned char *)control1;
    const unsigned char *ctrl2 = (const unsigned char *)control2;
    unsigned char map1[32],map2[32];
    static char *nextoken;
    static char flag=0;
    unsigned char c;
    int L;
    memset(map1,0,32);
    memset(map2,0,32);
    do {
        map1[*ctrl1 >> 3] |= (1 << (*ctrl1 & 7));
    } while (*ctrl1++);
    do {
        map2[*ctrl2 >> 3] |= (1 << (*ctrl2 & 7));
    } while (*ctrl2++);
    if (string) {
        if (control2[0]) {
            L=strlen(string);
            while (1) {
                c=string[L-1];
                if (map2[c >> 3] & (1 << (c & 7))) {
                    L--;
                    string[L]=0;
                } else break;
            }
        }
        if (control1[0]) {
            L=strlen(string);
            c=string[L-1];
            if (map1[c >> 3] & (1 << (c & 7))) {
                string[L]=control1[0];
                string[L+1]=0;
            }
        }
        str=(unsigned char *)string;
    }
    else str=(unsigned char *)nextoken;
    string=(char *)str;
    while (1) {
        if (0==flag) {
            if (!*str) break;
            if (map1[*str >> 3] & (1 << (*str & 7))) {
                *str=0;
                str++;
                break;
            } else if (map2[*str >> 3] & (1 << (*str & 7))) {
                string++;
                str++;
            } else {
                flag=1;
                str++;
            }
        } else if (1==flag) {
            if (!*str) break;
            if (map1[*str >> 3] & (1 << (*str & 7))) {
                *str=0;
                str++;
                flag=0;
                break;
            } else if (map2[*str >> 3] & (1 << (*str & 7))) {
                *str=0;
                str++;
                flag=2;
                break;
            } else str++;
        } else {//2==flag
            if (!*str) return NULL;
            if (map1[*str >> 3] & (1 << (*str & 7))) {
                str++;
                string=(char *)str;
                flag=0;
            } else if (map2[*str >> 3] & (1 << (*str & 7))) {
                str++;
                string=(char *)str;
            } else {
                string=(char *)str;
                str++;
                flag=1;
            }
        }
    }
    nextoken=(char *)str;
    if (string==(char *)str) return NULL;
    else             return string;
}
void main()
{
   strcpy(string,"A \tstring\t\tof ,,tokens\n\nand some  more tokens, ");
   strcpy(seps1,",\n");strcpy(seps2," \t");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"1234| LIYI|China | 010 |201110260000|OK");
   strcpy(seps1,"|");strcpy(seps2," ");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"1234|LIYI||010|201110260000|OK");
   strcpy(seps1,"");strcpy(seps2,"|");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"1234|LIYI||010|201110260000|OK");
   strcpy(seps1,"|");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"a");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"a,b");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"a,,b");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,",a");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,"a,");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,",a,,b");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,",,a,,b,,");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,",");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,",,");
   strcpy(seps1,",");strcpy(seps2,"");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
   strcpy(string,",,,");
   strcpy(seps1,",");strcpy(seps2," ");
   printf("\n[%s]\nTokens:\n",string);
   token=zzstrtok(string,seps1,seps2);
   while (token!=NULL) {
      printf(" <%s>",token);
      token=zzstrtok(NULL,seps1,seps2);
   }
}
//
//[A      string          of ,,tokens
//
//and some  more tokens,]
//Tokens:
// <A>, <string>, <of>, <>, <tokens>, <>, <and>, <some>, <more>, <tokens>, <>,
//[1234| LIYI|China | 010 |201110260000|OK]
//Tokens:
// <1234>, <LIYI>, <China>, <010>, <201110260000>, <OK>,
//[1234|LIYI||010|201110260000|OK]
//Tokens:
// <1234>, <LIYI>, <010>, <201110260000>, <OK>,
//[1234|LIYI||010|201110260000|OK]
//Tokens:
// <1234>, <LIYI>, <>, <010>, <201110260000>, <OK>,
//[a]
//Tokens:
// <a>,
//[a,b]
//Tokens:
// <a>, <b>,
//[a,,b]
//Tokens:
// <a>, <>, <b>,
//[,a]
//Tokens:
// <>, <a>,
//[a,]
//Tokens:
// <a>, <>,
//[,a,,b]
//Tokens:
// <>, <a>, <>, <b>,
//[,,a,,b,,]
//Tokens:
// <>, <>, <a>, <>, <b>, <>, <>,
//[,]
//Tokens:
// <>, <>,
//[,,]
//Tokens:
// <>, <>, <>,
//[,,,]
//Tokens:
// <>, <>, <>, <>,

再供参考:

//凡是?。!后面跟1~1000后面跟半角.的,在?。!后面加回车换行。
//in.txt:
//1.测试。2.测试2?3.测试3!4.测试
//四。5.测试。6.测试6?7.测试3!8.测试
//运行该程序将输出重定向到例如out.txt即可将输出保存到文件out.txt中
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
int main() {
    wifstream wifs("in.txt");
    wifs.imbue(locale("chs"));
    wstring wstr(L""),wln;
    while (wifs) {
        getline(wifs,wln);
        wstr+=wln;
    }
    wifs.close();
    wcout.imbue(locale("chs"));
    wcout << wstr << endl;
    wstring rs = L"([?。!])(\d{1,3}\.)";
    wregex expression(rs);
    wstr = regex_replace(wstr, expression, wstring(L"$1\r\n$2"));
    wcout << wstr << endl;
    return 0;
}
//1.测试。2.测试2?3.测试3!4.测试四。5.测试。6.测试6?7.测试3!8.测试
//1.测试。
//2.测试2?
//3.测试3!
//4.测试四。
//5.测试。
//6.测试6?
//7.测试3!
//8.测试
//

3

double max = double.Parse(lines[0].Replace(” “, “”).Split(new char[] { “=”, “;” })[1]);    //修改的代码
double min = double.Parse(lines[0].Replace(” “, “”).Split(new char[] { “=”, “;” })[1]);    //修改的代码
double money = double.Parse(lines[i].Replace(” “, “”).Split(new char[] { “=”, “;” })[1]);    //修改的代码

3

Replace(” “, “”)
你没看到本人先把空格删去了吗?
当然,C# 还提供了更人性的写法
lines[0].Split(new string[] { “=”, ” “, “;” }, StringSplitOptions.RemoveEmptyEntries)

3

没细看你的全部代码,string[] rowLines = lines[0].Split(new char[] { “=”, ” “, “;” }, StringSplitOptions.RemoveEmptyEntries);
空格只能有1个,split方法是按照给定的字符进行分割,后面加上StringSplitOptions.RemoveEmptyEntries即可清除空字符串。

3

lines[0].Split(new char[] { “=”, “;” })
是按 = 和 ; 切割成数组
空格依然存在于被切割的数组成员中,但已经不影响 double.Parse 的工作了
double.Parse 只在不合法的数据时(例如空串)产生错误
而你
double max = double.Parse(lines[0].Split(new char[] { “=”, ”  “, “;” })[1]);    //修改的代码
把 张三 = 1800; 切割成了 6 段,明显下标 1 是空串

3

你本人看清楚了,你红框框起的是
Split(new char[] { “=”,  “;” })
而不是
Split(new char[] { “=”, ”  “, “;” })
这就差的多了去了

3

为什么要睁着眼睛说瞎话呢?
话题:学习交流C#读取本文文件中内容出错
话题:学习交流C#读取本文文件中内容出错

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明话题:学习交流C#读取本文文件中内容出错
喜欢 (0)
[1034331897@qq.com]
分享 (0)