case 3:后面必须加break;case  3:
pbook.Erase();
break;

解决方案 »

  1.   

    以下以我用的正式版为准
    >>pw.WriteString(m_record.phone);//  'System.IO.BinaryWriter'  does  not  contain  a  definition  for  'WriteString'<<
    BinaryWriter下面没有WriteString的方法,写字符串是通过重载Write(string)来实现的>>  m_record.age=s_temp.ToUInt16;//  'string'  does  not  contain  a  definition  for  'ToUInt16'<<
    s_temp是字符串变量不能用Toxxx的方法转换(虽然所有对象都有ToString()的方法,但没有Toxxx其他的方法了),要通过Convert类库来转
    Convert.ToUInt16(string)来实现
      

  2.   

    恭喜 Ninputer(装配脑袋) 升级了!
      

  3.   

    using System;
    using System.IO;namespace 通讯录{
    struct Record
    {
    public string name;
    public UInt16 age;
    public string phone;
    public string address;
    }
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class PhoneBook
    {
    FileStream f_srm;
    string s_filename;
    Record m_record;
    public PhoneBook(string filename)
    {
    s_filename=filename;
    }
    public int Open()
    {
    Console.WriteLine("1.List Record");
    Console.WriteLine("2.Add New Record");
    Console.WriteLine("3.Erase Record");
    Console.WriteLine("0.Exit");
    Console.WriteLine("Programmer:Phoineer Stuido (C) .2001.");
    int i=Console.Read()-'0';
    return i;
    } public void AddNew()
    {
    try
    {
    f_srm=new FileStream(s_filename,FileMode.OpenOrCreate);
    }
    catch
    {
    Console.WriteLine("PhoneBook Error!");
    return;
    }
    BinaryWriter pw=new BinaryWriter (f_srm);
    pw.Seek(0,SeekOrigin.End); //Seek起什么作用?(0,SeekOrigin.End)是什么意思?
        string s_temp;
    Console.Write("Name:");
    Console.ReadLine(); //为什么要这一句(如不要则运行时产生The format of age is error,please ReEnter)
    m_record.name=Console.ReadLine();
    pw.Write(m_record.name); reenter:
    Console.Write("Age:");
    s_temp=Console.ReadLine();
    try
    {
    m_record.age=Convert.ToUInt16(s_temp); //请介绍一些关于Convert的知识,我买的书中没找到它 }
    catch
    {
    Console.WriteLine("The format of age is error,please ReEnter");
    goto reenter;
    }
    pw.Write(m_record.age);
    Console.Write("Phone Number:");
    m_record.phone=Console.ReadLine();
    pw.Write(m_record.phone);
    Console.Write("Address:");
    m_record.address=Console.ReadLine();
    pw.Write(m_record.address);
    f_srm.Close(); }
    public void List()
    {
    try
    {
    f_srm=new FileStream(s_filename,FileMode.Open);
    }
    catch
    {
    Console.WriteLine("PhoneBook Error!");
    return;
    }
    BinaryReader pr=new BinaryReader(f_srm);
    Console.WriteLine("Name Age Phone Number Address");
    Console.WriteLine("********************************************");
    while(true) //这个循环是怎么一回事,什么时候退出
    {
    try
    {
    m_record.name=pr.ReadString();
    m_record.age=pr.ReadUInt16();
    m_record.phone=pr.ReadString();
    m_record.address=pr.ReadString(); //请介绍一下以上四句是怎么读出的,编译器怎么定位
    }
    catch{return;}
    Console.WriteLine("{0,-9}{1,-6}{2,18}{3}",m_record.name,m_record.age,m_record.phone,m_record.address); //输出时{}中的参数是怎么回事 }
    f_srm.Close(); }
    public void Erase()
    {
    try
    {
    f_srm=new FileStream(s_filename,FileMode.Create); //请解释一下FileMode.Create与FileMode.OpenOrCreate的差异
    }
    catch
    {
    Console.WriteLine("PhoneBook Error!");
    return;
    }
    f_srm.Close();
    Console.WriteLine("Now the book is empty!"); } }
    class Class1
    {
    public static void Main() //下面这段程序我改了之后错在什么地方(编译能通过,执行出错)
    {

    PhoneBook pbook=new PhoneBook("E:\\学习作品\\通讯录\\bin\\Debug\\phonebook"); //为什么要用\\而不能用\

    while(true){
     int i=pbook.Open();


    switch (i)
    {
    case 0:break;
    case 1:
    pbook.List();
    break;
    case 2:
    pbook.AddNew();
    break;
    case 3:
    pbook.Erase();
    break;
    }if(i==0)break;
    }
    }
    }
    }
      

  4.   

    谢谢jhnhu,我又有一些问题,望解答
      

  5.   

    >>pw.Seek(0,SeekOrigin.End);<<
    把写入(或读取)的地方指向这个流(文件)的末尾,这样再写入时就不会覆盖原来的内容。
    具体请参考这个sample
    ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfsystemioseekoriginclasstopic.htm>>Console.Write("Name:");
    >>Console.ReadLine();     //为什么要这一句(如不要则运行时产生The format of age is error,please ReEnter)
    >>m_record.name=Console.ReadLine();
    >>pw.Write(m_record.name);
    出现错误是因为输入的name和age给错了变量,导致一个不是只有数的字符变量无法转换成数值型变量。为什么会给错了,因为作者(原来不是你写的)想要输入的界面好看,希望能在Name后面直接输入姓名,而不是Name一行,输入在另一行。而输入给变量的时候是用readline的,那这个Name到底算不算姓名的一部分呢?作者发现通过加一个readline可以解决这个问题,于是
    调试方法:在vs.net中,在后面的try上按F9,设置一个断点,运行到输入会回到程序中,你把鼠标移到m_record.name和s_temp上,看看他们的值是什么(有readline那行和没有,分两次比较一下)Convert类,在vs.net环境下键入Convert. 之后就会列出可转换成的类型,很方便的。请好好利用手上的资料,如MSDN,有很详细的文档和sample,搜索一下就可以了。
    先敲这么多
      

  6.   

    谢谢jhnhu:
        我还是没弄懂是怎么回事:
    >  >  Console.Write("Name:");
     >  >  Console.ReadLine(); //把这一句去掉后,
      >  >  m_record.name=Console.ReadLine();//这一句为什么就不执行呢?
      >  >  pw.Write(m_record.name);还有这一段:
    public static void Main() //下面这段程序我改了之后错在什么地方(编译能通过,执行出错)
    {
    while(true){
    PhoneBook pbook=new PhoneBook("E:\\学习作品\\通讯录\\bin\\Debug\\phonebook");  int i=pbook.Open();
            if(i==0)break;
    if(i==1) pbook.List();
    if(i==2) pbook.AddNew();
    if(i==3) pbook.Erase();
    }
    }希望jhnhu兄能回答,如有其它问题,将另开贴;
    最后一个问题:
    怎么把分给你?
      

  7.   

    1>>Console.Write("Name:");
    2>>Console.ReadLine();          //为什么要这一句(如不要则运行时产生The  format  of  age  is  error,please  ReEnter)
    3>>m_record.name=Console.ReadLine();
    4>>pw.Write(m_record.name);
    5>>reenter:
    6>>Console.Write("Age:");
    7>>s_temp=Console.ReadLine();ReadLine()的作用是接收一行输入的信息
    而输入的那行是由 程序打印的Name 和 用户输入的姓名 混合成的
    Name:jhnhu
    2>>Console.ReadLine();  //这行得到 "Name:"
    3>>m_record.name=Console.ReadLine();  //这行得到 "jhnhu"
    如果不混合可以分两行来做
    Name:      //WiteLine("Name:");
    jhnhu      //m_record.name=Console.ReadLine();
    这样就不用2了,但没有一行的好看
    但6 7之见为何没有ReadLine()我就不知道了
      

  8.   

    jhnhu:
        我试过你所说的方法,但不行.在第一行改为Console.WritLine("Name")后,取消第二行,编译后运行,显示:
    Name:
    Age:
    输入字母出错!
    还有最关键的是这段:(我是怎么也搞不懂了)
      public  static  void  Main()   //下面这段程序我改了之后错在什么地方(编译能通过,执行出错)
          {
            while(true){
            PhoneBook  pbook=new  PhoneBook("E:\\学习作品\\通讯录\\bin\\Debug\\phonebook");             int  i=pbook.Open();
                            if(i==0)break;
              if(i==1)  pbook.List();
              if(i==2)  pbook.AddNew();
              if(i==3)  pbook.Erase();
              }
          }
      

  9.   

    难得周末有点时间,还要给你调程序
    这家伙的水平也太差了吧!编程风格十分恶劣!快把这本书扔了吧,浪费大家的时间!你改的循环没有问题,出错是由这家伙的,投机取巧的心理造成的
    public  int  Open()
    {
    Console.WriteLine("1.List  Record");
    Console.WriteLine("2.Add  New  Record");
    Console.WriteLine("3.Erase  Record");
    Console.WriteLine("0.Exit");
    Console.WriteLine("Programmer:Phoineer  Stuido  (C)  .2001.");
    int  i=Console.Read()-'0';  //这是非常不好的做法,根本就不知道其中的原理,而这个应该是在C的时候就会有的问题
    return  i;
    }
    为了能简单地取得这个数字,用char减char得到int(这里用了隐式地使用了类型转换,初学者会看不懂)。既然需要char就不能用ReadLine(),数字是得到了,但在你按下回车的时候,却把 chr(13) chr(10)这两个字符留在了缓冲区中(13是回车-把光标移到第一列;10是换行-把光标移到下一行;这两个字符才是你看见按回车后换了一行的效果)。
    为什么选了1以后会显示3次菜单,第一次显示后Read()从缓冲里拿了chr(13)这个字符;第二次显示后Read()拿了chr(10)这个字符;第三次显示后,因为缓冲空了,所以才停下来等你输入。如果你在输入1的地方输入111,它肯定会显示5次。
    这也造成了在AddNew()需要添加一行ReadLine()来清空缓冲区里的东西,而后面的输入没有前没有这个语句,如果不清空,Name得到的是chr(13)chr(10),也就是一个空字符串,然后age得到你输入的姓名(这当然不能转换成数值型啦)。那家伙还以为是输入Name时有问题,结果给他碰对了,暂时不会出错,多么愚蠢啊!只要把Read()那行换成:
    int i = Convert.ToInt16(Console.ReadLine());
    把多出来的ReadLine();去掉,一切都会正常!还有这里
    while(true)     //这个循环是怎么一回事,什么时候退出
    {
    try
    {
    m_record.name=pr.ReadString();
    m_record.age=pr.ReadUInt16();
    m_record.phone=pr.ReadString();
    m_record.address=pr.ReadString();
    }
    catch{return;}   //文件读到末尾不能再读了,会出错,就会执行catch里的命令,达到跳出循环的目的
    Console.WriteLine("{0,-9}{1,-6}{2,18}{3}",m_record.name,m_record.age,m_record.phone,m_record.address);   }
    多么野蛮啊!要是各位来写,肯定是用 判断到文件尾了没有 来做循环条件的。关于参考资料,第一是微软的文档,能啃E文,绝对比别人学得快;还有论坛上推荐的书也可以买。
      

  10.   

    谢谢jhuhn:
        谢谢你如此耐心的回答,我将给你加分,已表感谢!
        再问一个问题,怎么判断到了文件尾,来做循环条件?
      

  11.   

    .net提供的类库中有很多stream对象可以对文件进行操作,有些有相同的效果。
    像这个BinaryReader有一个PeekChar()的方法
    public virtual int PeekChar();
    Returns the next available character and does not advance the byte or character position.
    Return Value:
    The next available character, or -1 if no more characters are available or the stream does not support seeking.
    (查一查文档就能知道的)
    所以把那个循环改为
    while(pr.PeekChar() != -1)
    {
    }
    就可以了,那个catch留着也行,以防有其他错误