【问题标题】:How to Use real string types to represent strings within a function of a class structure?如何使用真实的字符串类型来表示类结构函数中的字符串?
【发布时间】:2011-10-31 12:56:40
【问题描述】:

我的任务是输入一些学生数据,例如

  • 选项 1:输入学生姓名和 ID。
  • 选项 2:输入 i.d(根据学生 ID 验证 - 输入选项 1),为学生输入最多 10 个成绩,然后计算学生的平均成绩和字母成绩
  • 选项3:输出学生姓名、id和字母成绩。

程序必须以类类结构编写 - 在结构中声明变量和函数。

我还被赋予了使用班级结构输入 3 名学生的详细信息的任务。为简单起见,我现在只是为一名学生编写一个程序。

程序编译成功

第一个具体遇到的问题:当我选择选项“我”时,程序让我输入学生姓名,就是这样! - 出于某种原因跳过 id 输入并继续。

问题是我一直使用cin>>scanf() 作为我的主要输入法——但是这些和system("Pause") 并没有很好地为我服务——我知道system("pause") 不是很有效。过去,有人建议我使用真正的字符串类型来表示 std::string 类来自 <string> 库的字符串。

因此,我将感谢任何有关字符串类的帮助,以便我了解它们。

我相信我的程序可能还有其他一些问题,但任何关于字符串类的建议和我的“第一个具体遇到的问题”都会有所帮助。

所以我写了下面的程序来代表我的答案。

#include <iostream>
#include <cstdio>
#include <math.h>
using namespace std;


  struct classroom{

     char name;
     int student_id;
     float grades[10];
     int num_tests;
     float average;

     float letter_grade;
     void enter_name_id(void);
     void enter_grade(int);
     void average_grades(int);
     void letter_grades(void);
     void output_name_id_grade(void);

  };


     void classroom::enter_name_id(){

          cout<<"\n Please enter name of student: \n"<<"\n";

          cin>>name;
          cout<<"\n Please enter student i.d number: \n"<<"\n";
          scanf("%d",student_id);

          cout<<"\n"<<student_id;

        system("PAUSE");

     }

     void classroom::enter_grade(int n_tests){

          if(n_tests<=10){

             cout<<"\n Please enter student test grade: \n"<<"\n";
             cin>>grades[n_tests];

          }
          else{

             cout<<"\n You have reached your max number of grades entered!!"<<"\n";     

          }

         system ("PAUSE");
     }


     void classroom::average_grades(int n_tests){


          float sum=0;
          int i;

          for(i=0;i<n_tests;i++){

                    sum =sum+grades[i];             

          }
          average=sum/(float)n_tests;
          system ("PAUSE");
     }




     void classroom::letter_grades(void){

                if(average>=90){

                    letter_grade=65;   
                }
                if(average>=80&&average<90){

                    letter_grade=66; 
                }
                 if(average>=70&&average<80){

                    letter_grade=67; 
                }
                 if(average>=60&&average<70){

                    letter_grade=68; 
                }
                 if(average<60){

                    letter_grade=70; 
                }
                system ("PAUSE");
     }

     void classroom::output_name_id_grade(void){

           cout<<"\    Name     I.D   Grade "<<"\n";  

           cout<<name <<"      ";
           cout<<student_id<<"      ";
           cout<<(char)letter_grade<<"\n";  
           system ("PAUSE");
     }


int main()
{       
    classroom a;
    char  option,answer,ans;
    int a_num_tests, id;
    a_num_tests=0;


 for( ; ;){

 cout<<"\nEnter 'I' for Name and I.d, 'G' for grades or 'O' for Data output "<<"\n";

              cin>>answer;
              switch(answer){

                           case'I':

                                    a.enter_name_id();
                                    break;
                           case'G':
                                cout<<"\n Please enter student i.d number: "<<"\n";
                                scanf("%d",id);
                                cout<<"\n"<<id;
                                if(id==a.student_id){

                                    a_num_tests++;
                                    a.enter_grade(a_num_tests);
               cout<<"\n Would you like to enter another grade?   'Y' or 'N': "<<"\n";
                                    cin>>ans;

                                    while(ans=='y'||'Y'){
                                       a_num_tests++;

                                       a.enter_grade(a_num_tests);
               cout<<"\n Would you like to enter another grade? 'Y' or 'N': "<<"\n";
                                       cin>>ans;
                                    }

                                    a.average_grades(a_num_tests);
                                    a.letter_grades();

                                }
                                else{

                  cout<<"\n You have entered the wong i.d number!!! \n"<<"\n";

                                break;
                           }


                           case 'O':

                                a.output_name_id_grade();
                                break;
                           default:
                                cout<<"\n Wong Entry "<<"\n";
                                break;
                }
 }
 system ("PAUSE");
 return 0;

}

【问题讨论】:

  • 为什么把C的scanf和C++的cin混在一起?作为一名 c++ 程序员,我永远无法成功地让 c 的函数正常工作。
  • 如果这是家庭作业,请确保将问题标记为这样,因为假装明显的课堂练习是“真正的”编程问题被认为是一种糟糕的形式(并且响应的方法非常不同)。
  • 不,Kerrek SB 这不是课堂作业问题,问题来自教科书,我正在自学
  • Hossein - 没有意识到 scanf() 是 C 的,而 cin 是 C++ 的,所以现在我知道了! - 谢谢。
  • 就像@Hossein 所说,不要将cin 与旧的C 函数(如scanf)混合,输入缓冲很可能无法处理它。使用其中一种。

标签: c++ string class function


【解决方案1】:

再次感谢所有想知道的人,这段代码对我有用:

     void classroom::enter_name_id(void){

           cout << " Please enter your name\n>";
           std::cin.ignore( 25, '\n' );
           cin.getline( name,25);

           cout << " Type id\n>";
           cin>>student_id;
     return;
     }

不确定这条线是如何工作的:'std::cin.ignore(25, '\n');'!!! 但是为了防止编译器跳过,它需要的越少越好 下一行:'cin.getline(name,25);'

最初我在类函数中只使用 'cin>>name' 时遇到问题,这就是为什么我要询问其他真实字符串类型的问题。

如果有人对此问题有更多要补充的,请这样做。

我想再次感谢所有为我们共同取得的进步做出贡献的粉丝。

继续航行……

【讨论】:

  • "最初我在类函数中使用 'cin>>name' 时遇到问题" - 应该是:最初我在 'struct' 函数中使用 'cin>>name' 时遇到问题.
【解决方案2】:

有很多话要说...你为什么要写&lt;&lt; "\n" &lt;&lt; "\n"??无论如何,您可以将整个字符串放在一起,&lt;&lt; "\n\n"...。

对于输入/输出,坚持使用 iostream,不要无故混搭 C 库函数。或许是这样:

std::string name;
int         id;

std::cout << "Please enter your name: ";
std::getline(std::cin, name);

std::cout << "Please enter the ID: ";
std::cin >> id; // see below

也许this answer 对你有用。如果您想编写严肃的代码,则应检查输入操作是否有错误。

请注意,令牌提取 (&gt;&gt;) 会逐字读取,因此 std::cin &gt;&gt; name 只会读取一个单词。对于类似名字的东西,我们更喜欢getline()

如果你从命令行运行你的程序,你也不需要所有system("pause") 调用...

更新: 将令牌提取 (&gt;&gt;) 与行读取 (getline()) 混合通常不是一个好主意,因为前者不会吞噬换行符,而后者会。最好只使用两者之一,以更适合输入格式为准。

如果您只使用行读取,您仍然必须处理每一行,可能再次通过标记提取。为此,您需要一个字符串流。包括 &lt;sstream&gt; 并将最后一行替换为:

std::string line; // you can put this at the top with the other declarations
std::getline(std::cin, line);

std::istringstream iss(line);
iss >> id;

【讨论】:

  • 请注意,std::cin &gt;&gt; id 可能会将字符留在缓冲区中。使用std::cin.ignore( INT_MAX, '\n' ); 跟随它可能是个好主意,或者对所有输入使用std::getline,将行放入std::istringsstream 以进行转换。
  • @JamesKanze:很有可能;我还没有通读整个设计文档。不过,最好不要混合使用令牌提取和行读取,所以是的,getline() 始终是一个好主意。
  • @KerrekSB 如果您必须从错误中恢复,这种分离特别有用,因为它提供了一个自动重新同步点;扔掉你发现错误的那一行,然后换一个新行再试一次。
  • 感谢 James,您能否更具体地了解使用 std::istringsstream 转换 std::getline。即一个实际可行的代码示例?
  • @user993858:这已经在 StackOverflow 上完成了一百万次;只需搜索一下,您就会发现。如果你真的想要,我可以修改示例...
【解决方案3】:

scanf 导致缓冲区问题。使用后需要清除缓冲区。 fflush(stdin)。这将清除您的缓冲区,并且输入将停止 id 和其他输入。

您也可以使用getch() 代替system ("PAUSE");

【讨论】:

    猜你喜欢
    • 2017-05-21
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2016-07-25
    • 2021-09-20
    • 2017-06-13
    相关资源
    最近更新 更多