【问题标题】:Using strcmp with string arrays [closed]将 strcmp 与字符串数组一起使用 [关闭]
【发布时间】:2019-08-21 12:59:27
【问题描述】:

我正在编写一个测验程序,但我遇到了字符串数组和函数 strcmp 的问题

我想我可能不得不使用指针,但我不知道将哪个分配为指针

#include <iostream>
#include <cstring>
#include <stdio.h>
#include <string.h>
#include <cmath>

using namespace std;
int main(){
char question1[5][1000]={"Question #1\n\nWhat is the formula for the area of a square?\n\nA.) Area = (Side)(Side)\nB.) Area = Side + Side\nC.) Area = Base + Height\nD.) Area = (pi)(Radius)(Radius)\nAnswer: ",
"Question #2\n\nWhat is the perimeter of a rectangle with length = 4 and width =8?\n\nA.) Perimeter = 4 + 8 = 12 units\nB.) Perimeter = (4)(8) = 32 units\nC.) Perimeter = 2(4) + 2(8) = 24 units\nD.) Perimeter = [2(4)][2(8)] = 128 units\nAnswer: ",
"Question #3\n\nWhat is the circumference of a Circle with Diameter = 10 units?\n\nA.) Circumference = (pi)(5)(5) = 78.5 units\nB.) Circumference = 2(pi)(5) = 31.41 units\nC.) Circumference = (pi)(10)(10) = 314 units\nD.) Circumference = 2(pi)(10) = 62.8 units\nAnswer:",
"Question #4\n\nWhat is the measurement for the side of a square with Perimeter = 80?\n\nA.) 20 units\nB.) 80 units\nC.) 40 units\nD.) 50 units\nAnswer: ",
"Question 5\n\nWhat is the radius of a circle with area = 64pi square units?\n\nA.) 2pi units\nB.) 4pi units\nC.) 6pi units\nD.) 8pi units\nAnswer: "};
char answer1[5][2]={"A","C","B","A","D"};
char answer;
int score,i;
for(i=1;i<5;i++){
cout<<question1[i];
cin>>answer;
if(strcmp(answer,answer1[i])==0)
{
    score++;
}
}
cout<<"Your score is "<<score;
}

【问题讨论】:

  • 您还需要考虑用户输入的情况,因为“a”不等于“A”。使用 toupper(answer)。

标签: c++ loops initialization c-strings strcmp


【解决方案1】:

answer 是一个单个字符,而不是一个字符串。将其传递给期望字符串的函数时,不能将其用作字符串。对strcmp 的调用应该会导致编译器对此发出警告。

直接比较字符,例如answer == answer1[i][0].

或者将类型更改为字符串(最好是std::string,否则为char的数组)。


在不相关的注释中,您没有初始化变量score。这意味着它的值将是 indeterminate 并且使用它(如在score++ 中)将导致undefined behavior。

你需要显式初始化它:

int score = 0, i;

【讨论】:

    【解决方案2】:

    变量answer 被声明为一字节字符。

    char answer;
    

    它不能存储字符串。

    因此,您不能将标准函数 strcmp 与 char 类型的对象一起使用。

    你可以写

    if ( answer == answer1[i][0] )
    

    但最好将数组answer1声明为

    const char answer1[] = { "ACBAD" };
    

    或

    const char *answer1 = { "ACBAD" };
    

    并使用以下 if 语句

    if ( answer == answer1[i] )
    

    注意变量score没有初始化

    int score,i;
    

    你必须初始化它。而且循环中的索引应该从0开始。

    int score = 0;
    for( int i = 0;i < 5; i++ ){
    //...
    

    此外,使用5 之类的幻数也是一个坏主意。您可以引入一个命名常量。例如

    const size_t N = 5;
    char question1[N][1000] = { /*...*/ };
    //...
    for( size_t i = 0; i < N; i++ ){
    //...
    

    【讨论】:

      【解决方案3】:

      亲爱的 OP 请允许我直言不讳。那不是 C++,而是带有 iostreams 的 C 代码。也从未打印过第一个问题,发现了其他错误等。

      这些都不是问题,如果你愿意学习。 Here 是标准 C++ 工作版本。请与您的代码进行比较并研究它。

      // clang++ prog.cc -Wall -Wextra -std=c++17
      #include <iostream>
      #include <array>
      #include <string_view>
      
       using namespace std;
       // required for sv literal 
       using namespace std::literals;
      
       // compile time std array of string literals
       // each transformed to string_veiw's
       // by using the `sv` std defined literal
       constexpr array questions {
        "Question #1\n\nWhat is the formula for the area of a square?\n\nA.) Area = (Side)(Side)\nB.) Area = Side + Side\nC.) Area = Base + Height\nD.) Area = (pi)(Radius)(Radius)\nAnswer: "sv,
        "Question #2\n\nWhat is the perimeter of a rectangle with length = 4 and width =8?\n\nA.) Perimeter = 4 + 8 = 12 units\nB.) Perimeter = (4)(8) = 32 units\nC.) Perimeter = 2(4) + 2(8) = 24 units\nD.) Perimeter = [2(4)][2(8)] = 128 units\nAnswer: "sv,
        "Question #3\n\nWhat is the circumference of a Circle with Diameter = 10 units?\n\nA.) Circumference = (pi)(5)(5) = 78.5 units\nB.) Circumference = 2(pi)(5) = 31.41 units\nC.) Circumference = (pi)(10)(10) = 314 units\nD.) Circumference = 2(pi)(10) = 62.8 units\nAnswer:"sv,
        "Question #4\n\nWhat is the measurement for the side of a square with Perimeter = 80?\n\nA.) 20 units\nB.) 80 units\nC.) 40 units\nD.) 50 units\nAnswer: "sv,
        "Question #5\n\nWhat is the radius of a circle with area = 64pi square units?\n\nA.) 2pi units\nB.) 4pi units\nC.) 6pi units\nD.) 8pi units\nAnswer: "sv
         };
      
         // same compile time structure as questions
         // but for answers
         constexpr array answers {"A"sv,"C"sv,"B"sv,"A"sv,"D"sv};
      
        int main()
       {
         char answer {};
         int score{} ;
         // answer counter starts from 0
         size_t j = 0;
          // standard C++ 'sequence' loop
          for ( auto & question : questions ) {
            cout << question;
            cin >> answer;
               if( answer == answers.at[j][0] ) score++;
               j++ ;
          }
            cout <<"Your score is "<< score;
            return 42 ;
        }
      

      有人甚至可能声称标准 C++ 很简单,看看这个。一个人只需要使用它。

      附录

      更好的设计是创建和操作单一结构,将答案和问题放在一起。一些横向思考总是有帮助的。

      // clang++ prog.cc -Wall -Wextra -std=c++17
      #include <iostream>
      #include <array>
      #include <string_view>
      #include <utility> // std::pair
      
      using namespace std;
      using namespace std::literals;
      
      constexpr std::array a_q_pairs {
          pair{ 'A', "Question #1\n\nWhat is the formula for the area of a square?\n\nA.) Area = (Side)(Side)\nB.) Area = Side + Side\nC.) Area = Base + Height\nD.) Area = (pi)(Radius)(Radius)\nAnswer: "sv } ,
          pair{ 'C', "Question #2\n\nWhat is the perimeter of a rectangle with length = 4 and width =8?\n\nA.) Perimeter = 4 + 8 = 12 units\nB.) Perimeter = (4)(8) = 32 units\nC.) Perimeter = 2(4) + 2(8) = 24 units\nD.) Perimeter = [2(4)][2(8)] = 128 units\nAnswer: "sv},
          pair{ 'B', "Question #3\n\nWhat is the circumference of a Circle with Diameter = 10 units?\n\nA.) Circumference = (pi)(5)(5) = 78.5 units\nB.) Circumference = 2(pi)(5) = 31.41 units\nC.) Circumference = (pi)(10)(10) = 314 units\nD.) Circumference = 2(pi)(10) = 62.8 units\nAnswer:"sv},
          pair{ 'A', "Question #4\n\nWhat is the measurement for the side of a square with Perimeter = 80?\n\nA.) 20 units\nB.) 80 units\nC.) 40 units\nD.) 50 units\nAnswer: "sv},
          pair{ 'D', "Question 5\n\nWhat is the radius of a circle with area = 64pi square units?\n\nA.) 2pi units\nB.) 4pi units\nC.) 6pi units\nD.) 8pi units\nAnswer: "sv }
       };
      
      int main()
      {
       char user_answer {};
       int score{} ;
      
       // single loop
       // requires no change on adding/removing answers/questions pairs
       // no need to code index checking
       for ( auto & a_and_q : a_q_pairs ) 
       {
          auto & answer = a_and_q.first ; // char
          auto & question = a_and_q.second ; // string_view
          cout << question ;
          cin >> user_answer;
          if( user_answer == answer ) score++;
        }
         cout <<"Your score is "<< score;
         return 42 ;
      

      }

      精心设计的数据结构和对其进行操作的简单算法。也许我会把那个Niklaus Wirth book 擦掉?

      必填WandBox is here。

      【讨论】:

      • 要“使用at 进行边界检查”,您必须处理产生的异常。相反,我建议static_assert 问题和答案的大小相同。
      • @MSalters 沉闷地指出,我在想 不 有两个结构,但一个,同时保留答案和问题,从而避免索引检查的需要......虽然我想我可能已经用新的东西来使 OP 的盘子超负荷了。
      猜你喜欢
      • 1970-01-01
      • 2018-02-03
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多