c ++程序

时间:2018-05-03 23:54:27

标签: c++

该程序的目的是将文件中的短语读入矢量并将短语转换为Pig Latin。当翻译的短语以Pig Latin输出时,另外一个" ay"在短语之后添加(不应该发生)。谁能发现为什么会这样?重要的是我修复它,因为它影响我需要输出的猪拉丁短语的总字母和总字符数。另外,我并没有要求任何人为我编写任何代码,但有关如何减少代码冗余的任何提示。我的课程成绩的一部分是效率,我通常会失去分数。

以下是代码:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <stdio.h>
#include <ctype.h>

using namespace std;

int main()
{ 
  ifstream in;
  string word, fileName;
  vector <string> phrase;
  int length = 0, index = 0;
  int totalWords = -1, totalLetters = -3, totalChars;

  cout << "PIG LATIN PROGRAM" << endl; 
  cout << "Which file are you accessing? : ";
  cin >> fileName;

  fileName += ".txt";

  in.open(fileName);

  if (in.fail()) cout << "\nFile not found!" << endl;

  while(getline(in, word)) phrase.push_back(word);

  cout << "Original Phrase: " << phrase[0] << endl;

  istringstream iss(phrase[0]);

  cout << "Pig Latin phrase: ";
  do { 
    string OGword;
    string PLword;

    for (int i=0; i < phrase.size(); i++){ 
      iss >> OGword;
      totalWords++;
    }

    if (OGword[0]=='a' || OGword[0]=='A' || OGword[0]=='e' || OGword[0]=='E' || OGword[0]=='i' || OGword[0]=='I' || OGword[0]=='o' || OGword[0]=='O' || OGword[0]=='u' || OGword[0]=='U'){ 

      cout << OGword << "way" << " ";
      totalLetters += (OGword.size() + 3);
    }
    else {

      PLword = OGword.substr(index);
      length = PLword.length();

      PLword.insert(length, "ay");
      PLword.insert(length, 1, OGword[index]);
      PLword.erase(0, 1);
      if (isupper(OGword[0])){ 
        transform(PLword.begin(), PLword.end(), PLword.begin(), ::tolower); 
        (toupper(PLword[1]));
        char    upper;

        upper = toupper(PLword[0]);
        PLword.erase(0, 1);
        cout << upper;           
      }
      cout << PLword << " ";  
      totalLetters += PLword.size();
    }      
  } while (iss);  

  totalChars = totalLetters + 1;

  cout << "\n\nTotal words: " << totalWords << endl;
  cout << "Total Letters: " << totalLetters << endl;
  cout << "Total Characters: "<< totalChars << endl;
}

1 个答案:

答案 0 :(得分:0)

问题

程序的核心循环看起来像这样(伪代码):

istringstream iss; // Contains line of text.
do {
    string OGword;

    get_OGword_and_count_totalWords(iss, OGword);
    print_pig_latin_of_word(OGword);
} while (iss);

只要iss没有遇到错误,循环就会运行。特别是,iss在提取操作失败之前不会出现错误。所以事情发生在这样的循环中:

  • OGword包含该行的最后一个合法字词。
  • 打印最后一个字。
  • 测试了while子句。此时iss仍然很好,因为即使iss位于字符串的末尾,也没有发生错误。
  • 尝试将单词提取到OGword。这会失败,并使OGword为空(&#34;&#34;)。
  • 打印Pig#拉丁文版&#34;&#34;,这是&#34; ay&#34;。
  • 测试了while子句。 iss处于错误状态,循环结束。

修复

许多可能的修复方法是在提取单词后立即测试iss错误。

std::istringstream iss; // Contains line of text
std::string OGword;
while (iss >> OGword) {
    increment_word_total();
    print_pig_latin_of_word(OGword);
}

在此版本中,操作iss >> OGword返回iss,转换为bool。如果在前一次提取过程中出现错误,则循环结束而不打印任何内容。

其他建议

我认为提高可读性的最佳方法是将代码分解为更小的函数。例如,使用格式化并打印Pig Latin的if / else块,并将其实际放入函数中:

int print_pig_latin_of_word_and_return_total_letters(string_view word);

然后,该函数中的代码可以进一步细分:

bool starts_with_vowel(std::string_view word);
int print_vowel_word_and_count_letters(std::string_view word);
int print_consonant_word_and_count_letters(std::string_view word);

int print_pig_latin_of_word_and_count_letters(std::string_view word) {
    if (starts_with_vowel(word)) {
        return print_vowel_word_and_count_letters(word);
    } else {
        return print_consonant_word_and_count_letters(word);
    }
}

赔率和结束

我会删除using namespace std并将所有std库名称写为std::string等。这样就可以清楚标准库中的内容。

该程序对包含多行的输入文件具有有趣的行为。有一个for循环遍历phrase.size(),这是输入行的数量。这会导致单词被跳过而totalWords不正确。

此声明没有做任何事情,因为忽略了toupper的结果:

(toupper(PLword[1]));