C++学习之路(五),C++primer plus 第六章 分支语句和逻辑运算符-编程练习

本文介绍了C++编程中使用分支语句和逻辑运算符解决实际问题的四个练习,包括读取用户输入并转换字符、计算数字平均值、创建菜单驱动程序以及处理不同类型捐赠的情况。在实践中,作者详细讨论了如何处理非数字输入、循环结构、switch语句和结构体的使用,以及动态分配的结构数组。文章还探讨了在遇到问题时的思考和解决方案,如使用cin的类型检查和break语句的正确使用。

   1. 编写一个程序,读取键盘输入,直到遇到 @ 符号为止,并回显输入(数字除外),同时将大写字符转换为小写,将小写字符转换为大写(表忘了 cctype 函数系列)。

#include<iostream>
#include<cctype>
using namespace std;

int main()
{
	char ch;
	cout << "Enter the characters: ";
    // 曾经想过这里要完善题目要求这里 while可不可以加上 && !isdigit(ch),发觉不可行,这样输入字符 @ 或者输入数字程序就终止了
	while ((ch = cin.get()) != '@')
	{
		if (islower(ch))            // 小写字母
			ch -= 32;
		else if (isupper(ch))        // 大写字母
			ch += 32;
        // 于是只有在这里再加上一个 if 判断语句,来判断是不是数字
        else if (isdigit(ch))
            continue;                // 如果是数字跳过循环体余下部分直接跳到 while语句
		else
			ch;                     // 其实我并不知道这最后一个else怎么写来着
		cout << ch;
	}
	return 0;
}

   这段代码只完成了上述两项要求,还有关于数字的不显示未达到,现要去车站买票回蕲春
         
   2. 编写一个程序,最多将10个 donation 值读入到一个 double 数组中(如果愿意可以使用模板类 array)。程序遇到非数字输入时将结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。(把第二题留在上面,回家没事想想代码如何写)。应该是先声明一个变量 i ,取值范围0-8,读取到 double 数组中;吃点东西再写代码

#include<iostream>
using namespace std;

const int Max = 10;

int main()
{
    int i, j;
    double arr[ Max], total = 0.0, results = 0.0
    cout << "输入数字,你最多可以将10个数值保留备用: ";
    
    for (i = 0; i < Max; i++)
    {
        while (!(cin >> arr[ i ]))
        {
            cin.clear();
            while (cin.get() != '\n')
                 continue;
                cout << "输入类型错误,请重新输入: ";
        }
    }
    cout << "你输入的" << Max << "个数分别是: ";

    for (i = 0; i < Max; i++)
    {
        cout << arr[ i ] << " ";
        total += arr[ i ];
    }
    cout << "你输入的" << Max << "个数的和是: " << total << endl;
    cout << Max << "个数的平均值是: " << total / Max << endl;

    cout << Max << "个数其中大于平均数值的数分别是: ";
    for(i = 0; i < Max; i++)
    {
        if (arr[ i ] > (total / Max))
        {
            cout << arr [ i ] << " ";
            j++;
        }
    }
    cout << "总共有" << j << "个数大于平均值" << endl;
    return 0;
}

   程序运行的结果
   其中在几个地方花费的了一些功夫,第一就是如何在输入非数字的时候终止程序,一开始我还以为是可以用!isdigit(),后来发现这个函数只能代表0-9,大于9的数也会出问题,而且小数也不在其范围内;看到网友写的代码,我貌似有点误解了题目的意思,网上的代码是输入非数字时终止程序,但还会计算输入错误之前的和和平均值,而我的意思以为是输入非数字直接终止程序,看来是有些问题,这个就再想想。在网上查了下代码,有的人提到 cin 这个标准的输入输出流对象,>>是数据析取运算符(将流中的数据送往变量中)——就是在这个过程对流中的数据进行类型检查 。 
   早上又完善了下代码:

#include<iostream>
using namespace std;

const int Max = 10;

int main()
{
	int i = 0, j = 0, count = 0;
	double donation[ Max ];
	double total = 0.0, results = 0.0;

	cout << "输入最少10个数: ";
	while (i < Max && cin >> donation[ i ])
	{
		cout << "donation[ " << i << " ] = " << donation[ i ] << endl;
				++i;
		if (!(cin))        //注意这里不能写成!(cin >> donation[ i ]),
			break;
	}
	for (j = 0; j < i; j++)
	{
		total += donation[ j ];
	}
	results = total / Max;
	cout << total << ", " << results << endl;
	cout << "输入了" << j << "个数在列, 其中和为: " << total << ", 平均值是: " << results << endl;

	cout << "输入了" << j << "个数在列, 其中大于平均值的数分别是: " << endl;
	for (j = 0; j < i; j++)
	{
		if (results < donation[ j ])
		{
			cout << "donation[ " << j << " ] = " << donation[ j ] << " " << endl;
			count++;
		}
	}
	cout << "你输入的数字共有 " << count << " 数字大于平均值: "<< endl;

	return 0;
}

   下面是全部输入数字的结果

   再就是输入中间有非数字的结果
   说明下:上面代码中的 if(!cin),不能写成 if(!(cin >> donation[ i ])),不然会隔一个数字读取一个数字,具体是什么原因暂时还没弄清楚;还有一点就是最后一个 for 循环,这里变量 j 一定要要小于等于 i ,由于上一个循环已经决定了 i 的次数,因为不确定输入会不会有非数字,因此不能用 j < Max。
   3. 编写一个菜单驱动程序的雏形。该程序显示一个提供4个选项的菜单-------每个选项用一个字母标记。如果用户使用有效选项之外的字母进行响应,程序将提示用户输入一个有效的字母,直到用户这样做为止。然后,该程序使用一条 switch 语句,根据用户的选择执行一个简单的操作。该程序的运行情况如下:
   Please enter one of following choices:
   c)    carnivore      p)    pianist
    t)    tree                           g)    game
    f
    Please enter a c,p,t,or   g:  
    Please enter a c,p,t,or   g:    
    A maple is a tree.

#include<iostream>
using namespace std;

void ShowMenu();

int main()
{
    ShowMenu();
    char choice;
    cin >> choice;
    while (cin)
    {
        switch (choice)
        {
            case 'c' : cout << "carnivore.\n";break;
            case 'p' : cout << "pianist.\n";break;
            case 't' : cout << "A maple is a tree.\n";break;
            case 'g' : cout << "game.\n";break;
            default  : cout << "Please enter a c, p, t, or g: ";
        }
            cin >> choice;
    }
    return 0;
}

void ShowMenu()
{
    cout << "Please enter one of the following choices:\n"
            "c) carnivore            p) pianist\n"
            "t) tree                 g) game\n";
}

   运行结果如下
   这个题目没什么要说的,主要还是代码的格式。
   4. 加入 Benevolent Order of Programmer 后,在 BOP 大会上,人们便可以通过加入者的真实姓名、头衔或秘密 BOP 姓名来了解此人。请编写一个程序,可以使用真实姓名、头衔、秘密改名或成员偏好来列出成员。编写该程序时,请使用下面的结构:
   // Benevolent Order of Programmers name stucture
   struct bop{
   char fullname[ strsize ];   // real name
         char title[ strsize ];     // job title
         char bopname[ strsize ];      // secret BOP name
         int preference;          // 0 = fullname, 1 = title, 2 = bopname
   };
   该程序创建一个由上述结构组成的小型数组,并将其初始化为适当的值。另外,该程序使用一个循环,让用户在下面的选项中进行选择:
   a.   display by name      b.   display by title
   c.    display by bopname    d.    display by preference
   q.    quit
   注意,“display by preference”并不是意味着显示成员的偏好,而是根据成员的偏好来列出成员。例如,如果偏好为1,则选择 d 将显示程序员的头衔。该程序运行情况如下:
   Benevolent Order of programmers Report
   a.   display by name      b.   display by title
   c.    display by bopname    d.    display by preference
   q.    quit
   Enter your choice: a
   Wimp Macho
   Raki Rhodes
   Celia Laiter
   Hoppy Hipman
   Pat Hand
   Next choice: d
   Wimp Macho
   Junior Programmer
   MIPS
   Analyst Trainee
   LOOPY
   Next choice: q
   Bye!

​
#include<iostream>
using namespace std;
void ShowMenu();

const int strsize = 20;

struct bop {
    char fullname[ strsize ];
    char title[ strsize ];
    char bopname[ strsize ];
    int preference;
};

bop info [ 5 ] = {
 	{"Wimp Macho", "BOSS", "Wp", 0},
	{"Raki Rhodes", "Manager", "Junior Programmer", 2},
	{"Celia Laiter", "MIPS", "Ca", 1},
	{"Hoppy Hipman", "Analyst Trainee", "Hy", 1},
	{"Pat Hand", "student", "LOOPY", 2},
};

int main()
{
    ShowMenu();
    char choice;
    cout << "Enter your choice: ";
    cin >> choice;

    while (choice == 'a' || choice == 'b' || choice == 'c' || choice == 'd')
    {
        switch (choice)
        {
            case 'a' :
            {
                for (int i = 0; i < 5; i++)
                    cout << info[ i ].fullname << endl;
                    break;
            }
            case 'b' :
            {
                for (int i = 0; i < 5; i++)
                    cout << info[ i ].title << endl;
                    break;
            }
            case 'c' :
            {
                for (int i = 0; i < 5; i++)
                    cout << info[ i ].bopname << endl;
                    break;
            }
            case 'e' :
            {
                for (int i = 0; i < 5; i++)
                {
                    if (info[ i ].preference == 0)
                        cout << info[ i ].fullname << endl;
                    else if(info[ i ].preference == 1)
                        cout << info[ i ].title << endl;
                    else
                        cout << info[ i ].bopname << endl;
                    break;
                }
            }
        }
        cout << "Next choice: ";
        cin >> choice;
    }
    cout << "Bye!\n";
    return 0;
}

void ShowMenu()
{
   	cout << "Benevolent Order of programmers Report\n"
		    "a. display by name \t b. display by title\n"
		    "c. display by bopname \t d. display by preference\n"
		    "q. quit\n";
}

​

   运行结果
   注意几点;声明结构和初始化结构的写法,第二个就是题目没有把初始化结构的数据一一列出来,导致题目有些模糊不清,第三个 case 'x' :后面的语句,如果是比如循环或者条件的多条语句,要把语句块先用大括号 { } 括起来,否则,在VC6里会报错,避免这种错误
  case:
  for (int i = 0; i < n; i++)
  {
    …………
  }
  break;
  …………
  修改为
  case:
  {
       for (int i = 0; i < n; i++)
    {
      …………
    }
    break;
  }
  另外一点,特别注意 break;这个语句是在 for 循环之外,如果被写到大括号内,也就是在循环体中,将会出现各种状况,虽然不是语法错误,但打印的结果灰常离普。还有就是 cout 输出语法,比如输出菜单之内的,输出多行,只用一个 cout 的话,只能有一个分号“;”,也就是结束语句的地方,其它地方不能用分号,否则也会是语法错误。
  “display by preference”并不是意味着显示成员的偏好,而是根据成员的偏好来列出成员。例如,如果偏好为1,则选择 d 将显示程序员的头衔。刚开始写代码的时候并没有看懂这句话是么意思,后来在网上找代码的时候,发现有一段代码是这样写的:
   cout << "Wip Macho\n" << "Junior Programmer\n" << "MIPS\n" << "Analyst Trainee\n" << "LOOPY\n";
当时我就认为这是在搞笑,可能笔者也没有弄清楚题目的意思,如果真的要这么写,出题的意思那就完全没需要了,就比如早些年接触过VB的时候课后有一题,打印一个由*号组面的三角形,要是按照刚才的代码,直接用 cout 写那就更JB简单了:
  print "      *" ;
  print "     ***" ;
  print "    *****" ;
  print "   *******" ;
  print "  *********" ;
  print " ***********" ;
  print "*************" ;
  5. 在 Neutronia 王国,货币单位是 tvarp,收入所得税的计算方式如下:
  5000 tvarps: 不收税
  5001 ~ 15000 tvarps: 10%
  15001 ~ 35000 tvarps: 15%
  35001 tvarps 以上:20%
  例如,收入为38000 tvarps 时,所得税为5000 * 0.00 +10000* 0.10 + 20000 * 0.15 + 3000 * 0.20,即4600 tvarps。请编写一个程序,使用循环来要求用户输入收入,并报告所得税,当用户输入负数或者非数字时,循环结束。(房间里睡觉打呼来了,晚上只有在办公室睡了,那么继续)

#include<iostream>
using namespace std;

int main()
{
	int tvarps;
	cout << "Enter your tvarps: ";
	while (cin >> tvarps && tvarps >= 0)
	{
		if (tvarps <= 5000)
			cout << "个人所得税为: 0 tvarps.\n";
		else if (tvarps >= 5001 && tvarps <= 15000)
			cout << "个人所得税为: " << 5000 * 0.00 + 10000 * 0.10 << " tvarps.\n";
		else if (tvarps >= 15001 && tvarps <= 35000)
			cout << "个人所得税为: " << 5000 * 0.00 + 10000 * 0.10 + 20000 * 0.15 << " tvarps.\n";
		else 
			cout << "个人所得税为: " << 5000 * 0.00 + 10000 * 0.10 + 20000 * 0.15 + 3000 * 0.20<< " tvarps.\n";
		cout << "Enter your tvarps: ";
		continue;
	}
		cout << "输入有误,程序即将终止.\n ";
	return 0;
}

  程序运行结果  

  先去洗澡了 

  下午是市公司仓库领材料,短袖衬衫和裤子都弄破了,真划不来,费话不说,继续。
  6. 编写一个程序,记录捐助给“维护合法权利团体”的资金。该程序要求用户输入捐献者数目,然后要求用户输入每一个捐献者的姓名和款项。这些信息被储存在一个动态分配的结构数组中。每个结构有两个成员:用来储存姓名的字符数组(或 string 对象)和用来存储款项的 double 成员。读取所有的数据后,程序将显示所有捐款超过 10000 的捐款者的姓名及捐款数额。该列表前应包含一个标题,指出下面的捐献者是重要捐款人(Grand patrons)。然后,程序将列出其他的捐款者,该列表要以Patrons 开头。如果某种类别没有捐款者,则程序将打印单词“none”.该程序只显示这两种类别,而不进行排序。
  期间我一直想写一段代码,意思大概是当输入回车的时候会显示一个菜单,提示继续输入还是输入完成回显输入结果,由于用到了while内嵌一个while而内嵌里面又有一个 switch ,当用case 输入的时候想回到第一个while时却不得其决,用 break 和 continue 只能到内嵌的 while循环里,怎么跳也跳不到第一个 while 循环上,后来在网上查资料,说可以用 goto语句,用了goto的确能达到我想要的结果,但资料上又说最好表用 goto语句,会影响程序的可读性,于是我就放弃了用goto的想法了,然后就题目简单的意思写了一段代码,其中题目所说到该列表要以Patrons开头,不知道是什么意思,下面是代码,基本上能达到题目的要求

#include<iostream>
using namespace std;

const int max = 10;

void ShowMenu();

struct info
{
	char name[ max ];
	double money;
};                                   // 表忘了这个分号

int main()
{

	int i = 0;
	char ch;
	
	info *ps = new info[ max ];
	
	cout << "输入捐款者姓名和捐款者金额: ";
	while (cin && i < max)
	{
		cin >> ps[ i ].name && cin >> ps[ i ].money;
		i++;
	}
	for (int j = 0; j < i; j++)
		cout << "ps[ " << j<< " ].name: " << ps[ j ].name << " " << "ps[ " << j << " ].money :" << ps[ j ].money << endl;
	cout << "其中标记为 GRAND patrons 的人有: \n";
	for (j = 0; j < i; j++)
	{
		if (ps[ j ].money >= 10000)
		cout << ps[ j ].name << ": " << ps[ j ].money << endl;
	}
	cout << "其中标记为 none 的人有: \n";
	for ( j = 0; j < i; j ++)
	{
		if (ps[ j ].money <= 100)
		cout << ps[ j ].name << ": " << ps[ j ].money << endl;
	}
    delete []ps;    // 释放内存表忘了
	return 0;
}

void ShowMenu()
{
	cout << "请选择输入有效的字符: \n"
			"a) 继续输入 \t" "b) 完成输入,并查看输入结果\n";
}

  程序运行如下:
  说实话,刚拿到题目的时候,我害怕的不是别的,而是害怕动态结构数组这个,只知道用new 来创建,而不知道代码该如何写。时间不早了,昨天晚上也没睡好,睡了,明天再看看网上的写法
  7. 编写一个程序,它每次读取一个单词,直到用户只输入 q。然后,该程序指出有多少个单词以元音打头,有多少个单词以辅音打头,还有多少个单词不属于这两类。为此,方法之一是,使用 isalphs() 来区分以字母和其他字符打头的单词;然后对于通过了 isalphs() 测试的单词,使用 if 或 swith 语句来确定哪些单词以元音打头。该程序的运行情况如下:
  Enter words (q to quit):
  The 12 awesone oxen ambled
  quietly across 15 meters of lawn. q

  5 words beginning with vowels
  4 words beginning with consonants
  2 others
  此题目首先要弄清楚两件事,第一,看清楚题目意思,注意第三行输入的英文最后一个字母 q ,它是单独的,并不是和lawn.q连起来的,第二,要知道单词的首字母表现方式,为了后面的我想了大半天,由于没看清楚题目的意思,又浪费了半天,不说了,都是泪,睡觉,明天再搞
  就是一直没弄清楚单词的第一个字母如何去访问,弄得我是一筹莫展,最后去网上找别人写的代码,才知道,可以用word[ 0 ]来访问,有了这个突破口,那么就比较简单了,看到网上几个代码都是用string这个关键字,由于我把输入的“quietly across 15 meters of lawn.  q”, 看到了“quietly across 15 meters of lawn.q”我就想这个应该最好用char 数组吧,因为可以用char 来读取每一个字符,只到碰到字符 q 的时候,程序终止,而如果用 string 的话,要么句尾单独打出一个q 才能终止程序,要么的话,就用strlen(word)来得到字符串word的长度,当读取word字符串的长度等于 strlen(word) ,也就是字符串的最后一个字符为 q 的时候程序才终止。后的是今天早上才想到的方法

//标准版
#include<iostream>
#include<cctype>
#include<string>
using namespace std;

int main()
 char word[ 20];    
    int vowels = 0, consonants = 0, others = 0;

    cout << "Enter words (to stop, tpye the word done): " << endl;
	
	while(cin >> word && strcmp(word, "q"))
    {
		if (word)
		{
			if ((word[ 0 ] >= 'a' && word[ 0 ] <= 'z') ||(word[ 0 ] >= 'A' && word[ 0 ] <= 'Z'))
			{
				if (word[ 0 ] == 'a' || word[ 0 ] == 'e' || word[ 0 ] == 'i'
					 || word[ 0 ] == 'o' || word[ 0 ] == 'u' ||word[ 0 ] == 'A' 
					 || word[ 0 ] == 'E' || word[ 0 ] == 'I'
					 || word[ 0 ] == 'I' || word[ 0 ] == 'U')
			
					vowels++;
				else 
					consonants++;
			}
			else
				others++;
		}
    }
	cout << "You entered a total of " << vowels << " beginning with vowels words. " << endl;
	cout << "You entered a total of " << consonants << " beginning with consonants words. " << endl;
	cout << "You entered a total of " << others << " beginning with others words. " << endl;
	
	return 0;
}

  运行结果:
  下面是简单扩展版,统计了所有单词,然后分别统计数字,元音打头、辅单打头和其它单词

// 简单扩展版,统计了所有单词,然后分别统计数字,元音打头、辅单打头和其它单词
#include<iostream>
#include<cctype>
#include<string>
using namespace std;

int main()
{
    char word[ 20];    
    int vowels = 0, consonants = 0, digit = 0, count = 0, others = 0;

    cout << "Enter words (to stop, tpye the word done): " << endl;
	
	while(cin >> word && strcmp(word, "q"))
    {
		if (word[ i ])
		{
			if (isdigit(word[ 0 ]))	// 如果单词的第一个字符是数字,则进入循环
			{//	cout << word << " ";
				digit++;
			}
			else if ((word[ 0 ] >= 'a' && word[ 0 ] <= 'z') ||(word[ 0 ] >= 'A' && word[ 0 ] <= 'Z'))
			{
				if (word[ 0 ] == 'a' || word[ 0 ] == 'e' || word[ 0 ] == 'i'
					 || word[ 0 ] == 'o' || word[ 0 ] == 'u' ||word[ 0 ] == 'A' 
					 || word[ 0 ] == 'E' || word[ 0 ] == 'I'
					 || word[ 0 ] == 'I' || word[ 0 ] == 'U')
			
					vowels++;
				else 
					consonants++;}
			
			else
				others++;
			}
			count++;					// 统计总单词数量
    }
	cout << "You entered a total of " << count << " words. " << endl;
    cout << "You entered a total of " << digit << " beginning with digit words. " << endl;
	cout << "You entered a total of " << vowels << " beginning with vowels words. " << endl;
	cout << "You entered a total of " << consonants << " beginning with consonants words. " << endl;
	cout << "You entered a total of " << others << " beginning with others words. " << endl;
	
	return 0;
}

  运行结果:

  下面是豪华加强版,除了上面的功能,还加了,上面提到的,还得判断一个单词最后个字符也是 q 的情况,也就是说上面第二句未尾的 lawn.q 和 lawn.   q 同样的结果:第一张图是  lawn.q --lawn.和q是连起来输入的
  第二张图是 lawn.   q ,--lawn. 和 q 是分开输入的

  无视中间打印出来的字符,那是我测试用的,OK到这里该打印出来的都打印出来了,基本上算是完美了,就是还差一点的就是利用书上说用 if  switch 实现,然后就是用string字符串还不是用char字符串数组来实现吧,这里又提到了实现,不过这个词用到这里的确是灰常的好。昨天看到有位写这个代码的时候用到一个 flag,查了下度度,说是一个标记变量,大概的意思就是,flag = true的时候进入下面语句,否则跳过下面一条语句而进入下下一条语句;或者 flag 为 true 的时候 contiune,反之则 break;最后那个代码写完后运行结果统计出来的数字也和书中不一样,那人自己也不知道问题出在哪,属于一个半成品。
  8. 编写一个程序,它打开一个文本文件(书上又写错字了,我去,改改~),逐个字符的读取该文件,直到到达文件未尾,然后指出该文件中包含多少个字符。

#include<iostream>
#include<fstream>
using namespace std;

const int size = 60;

int main()
{
    char filename[ size ];
    ifstream inFile;
    cout << "Enter name of data file: ";
    cin.getline(filename, size);
    inFile.open(filename);
    if (!inFile.is_open())
    {
        cout << "Could not open this file " << filename << endl;
        cout << "Program terminating.\n";
        exit(EXIT_FAILURE);
    }

    char ch;
    int count = 0;
    inFile >> ch;
    while (inFile.good())
    {
        ++count;
        inFile >> ch;
    }
    if (inFile.eof())
        cout << "End of file reached.\n";
    else if (inFile.fail())
        cout << "Input terminated by data mismatch.\n";
    else
        cout << "Input terminated for unknown reason.\n";
    if (count == 0)
        cout << "No data processed.\n";
    else
        cout << "You total input :" << count << " characters.\n";

    return 0;
}

  程序运行结果: ,期间我想输出文件包含多少个单词,将
  char ch;
  int count = 0, word = 0;
  inFile >> ch;
  while (inFile.good())
  {
    ++count;
     inFile >> ch;
      }

  改成
  string words;
  int count = 0, word = 0;
  inFile >> words;
  while (inFile.good())
  {
    count++;
    inFile >> words;
  }
  再进行输出的时候,到单词的个数,却不得其决……。打呼那人今天听说貌似回武汉了,几天晚上都没睡好,今天得早点回去洗洗睡了
  今天上午停了一上午的电,在办公室沙发上断断续续的睡了几觉,觉得睡得不舒服,跑去宿舍床上开着空调,结果在床上个把小时都没怎么睡着。继续当码。
  9. 完成编程练习6,但从文件中读取所需的信息。该文件的第一项应为捐款人数,余下的内容应为成对的行。在每一对中,第一行为捐款人姓名,第二行为捐款数额。即该文件类似于下面:
  4
  Sam Stone
  2000
  Ferida Flass
  100500
  Tammy Tubbs
  5000
  Rich Taptor
  55000
  此题一个关键的代码为: inFile.get()    //数字与字符交替输入时; 或者 叫抵消换行。一开始写了一个简单的读取文本文件的代码,要命的是只能读取第一行的数据,要么就是只能读取第一行和第二行的数据,第三是乱的,原先代码如下:

#include<iostream>
#include<fstream>
using namespace std;
const int size = 50;

struct info
{
    char name[ size ];
    double money;
};

int main()
{
    fstream infile;
    infile.open("myfile.txt);
    if (!infile.is_open())
    {
        cout << "Could not open this data file, please check it.\n";
        exit(EXIT_FAILURE)
    }

    int max, i = 0;
    infile >> max;
    info *ps = new info[ max ];    // 声明一个动态的结构数组
    cout << "max = " << max << endl;    // 测试下能不能读取第一个数字
    infile >> ps[ 0 ].name >> ps[ 0 ].money;
    cout << ps[ 0 ].name << ": " << ps[ 0 ].money; // 测试下能不能读取第一个元素

    return 0;
}
  我想先试下输出结果,然而:,第一行的结果已经没有问题,但第二却只打印出一个单词,而人名字有两个单词来着,这个应该是没什么问题,但第三打印的什么鬼?于是我把文本文件的第一行删除,随便加个for循环读取下面的内容
#include<iostream>
#include<fstream>
using namespace std;
const int size = 50;

struct info
{
    char name[ size ];
    double money;
};

int main()
{
    fstream infile;
    infile.open("myfile.txt);
    if (!infile.is_open())
    {
        cout << "Could not open this data file, please check it.\n";
        exit(EXIT_FAILURE)
    }

    int max, i = 0;
   // infile >> max;
    info *ps = new info[ max ];    // 声明一个动态的结构数组
   // cout << "max = " << max << endl;    // 测试下能不能读取第一个数字
    for (i = 0; i < 4; i++)
    {
        infile.geline(ps[ i ].name, size)
        infile >> ps[ i ].money;
        cout << ps[ i ].name << ": " << ps[ i ].money; // 继续测试下能不能读取
    }
    return 0;
}

  第一行人的名字倒是全部都能打印出来,第二行的金额也还行,可是
  这打印的又是什么鬼,竟然给我整一个非法,我用F10一步步的看代码,i = 0的时候完全没问题,继续
当i = 1 的时候我不知道它打印的是什么东西,下面都是差不多的了就不贴图了,为何只能读取第一次循环?(办公有个以前的上司抽烟,熏得我眼睛都睁不开了),把书翻到例子再看一遍,没有发现什么蛛丝马迹,没有办法了,只有找网上的代码看看我倒底错在哪了。于是就被我看到,之前我说到的关键代码:infile.get() 了。眼睛是有些受不了,回家了,明天再来码
  到办公室开着空调把门打开空气对流下。

//更改后代码如下:
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
const int size = 60;

struct info
{
	char name[ size ];
	double money;
};

int main()
{
	char filename[ size ];
	ifstream infile;
//	cout << "Enter your data filename: ";
//	cin.getline(filename, size);
	infile.open("MyFile.txt");
	if (!infile.is_open())
	{
		cout << "Could not open this file " << filename << ", please check it." << endl;
		cout << "Program terminating.\n";
		exit(EXIT_FAILURE);
	}

	int i = 0, max = 0;
	infile >> max;
	info *ps = new info[ max ];
	cout << "max = " << max << endl;
	
	for (i = 0; i < max; i++)
	{
	infile.get();
        infile.get(ps[ i ].name, size);
        infile >> ps[ i ].money;
	
		cout << ps [ i ].name << ": " << ps[ i ].money << endl;
	}
	return 0;
}

  可以加这里
  也可以这样加
  这里也可加上一条
  今天又学到一招,VC6查看汇编,先用F9在某句上下个断点,这一句前面有个红圈圈,然后按F5或者F10,不同的是F5直接来到下断点的语句处,而F10从main语句开始一步步运行:
  这是F5的效果:


然后我们按ctrl+F11,就可以看到汇编的代码了:
下面是F10的效果
  
  最重要的一行代码解决以后那么其它的就简单了,然后完整的代码为:

//完整的代码如下:
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
const int size = 60;

struct info
{
	char name[ size ];
	double money;
};

int main()
{
	char filename[ size ];
	ifstream infile;
//	cout << "Enter your data filename: ";
//	cin.getline(filename, size);
	infile.open("MyFile.txt");
	if (!infile.is_open())
	{
		cout << "Could not open this file " << filename << ", please check it." << endl;
		cout << "Program terminating.\n";
		exit(EXIT_FAILURE);
	}

	int i = 0, max = 0;
	infile >> max;
	info *ps = new info[ max ];
	cout << "max = " << max << endl;
	
	for (i = 0; i < max; i++)
	{
	infile.get();
        infile.get(ps[ i ].name, size);
        infile >> ps[ i ].money;
	
		cout << ps [ i ].name << ":\t" << ps[ i ].money << endl;
	}

    cout << "Grand Patrons: \n";
    for (i = 0; i < max; i++)
    {
        if (ps[ i ].money >= 10000)
            cout << ps[ i ].name << ":\t" << ps[ i ].money << endl;
    }

    cout << "Other Patrons:\n";
    for (i = 0; i < max; i++)
    {
        if (ps[ i ].money >= 0 && ps[ i ].money <= 10000)
        cout << ps[ i ].name << ":\t" << ps[ i ].money << endl;
    }

    cout << "None:\n";
    for (i = 0; i < max; i ++)
    {
        if (ps[ i ].money ==0)
            cout << ps[ i ].name << ":\t" << ps[ i ].money << endl;
    }
	return 0;
}

  代码运行结果如下
 


  下面也来个总结下
  ①:读取字符后保存到一个单词中,直接用 cin >> word,然后要访问该 word 的首字母可以用word[ 0 ],或者最后一个字母可以用wor[ strlen(word) ],其它情况依次类推。
  ②:case X : 后面如果有语句块,一定要用{ ...}把语句块括起来,这个貌似在我的VS2010里不需要用括号,不过在VC6里必须要用括号。
  ③:读取文本文件的时候,如果是字符串和数字交替的时候(可能是这种情况)要记得用上.get(),或者infile.get()。
  ④:还有什么?暂时就这么多吧。
  结下来,先回顾下,然后进入第七章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值