Мне нужно преобразовать некоторый код, чтобы он работал с текстом входного и выходного файлов

#c

#c

Вопрос:

У меня есть программа, которая меняет местами буквы в предложении, но сохраняет слова в том же порядке. Мне нужно изменить код из библиотеки iostream в библиотеку fstream, где пользователь вводит предложение во входной файл («input.txt «), и программа выводит обратное в выходной текстовый файл.

пример ввода:

 This problem is too easy for me. I am an amazing programmer. Do you agree?
  

Пример вывода:

 sihT melborp si oot ysae rof em. I ma na gnizama remmargorp. oD uoy eerga?
  

Код, который у меня уже есть:

 int main()
{
    int i=0, j=0, k=0, l=0;
    char x[14] = "I LOVE CODING";
    char y[14] = {''}; 
    for(i=0; i<=14; i  ) { 
        if(x[i]==' ' || x[i]=='')  {
            for(j=i-1; j>=l; j--) 
            y[k  ] = x[j];
            y[k  ] = ' ';  
            l=i 1;
         }
    } 

    cout << y;
    return 0;
}
  

Комментарии:

1. есть ли причина, по которой вы не используете std::string для этого?

2. Поместите имеющийся у вас код, который переворачивает слова, в функцию. Затем создайте цикл, который считывает входные данные, передает входные данные этой функции и выводит результат. Перед циклом откройте входные и выходные файлы по мере необходимости. Легко. На самом деле вам нужно сделать свою собственную домашнюю работу (вы не узнаете ничего полезного, если не сделаете этого), поэтому я оставлю создание кода в качестве упражнения.

3. Привет, Джаред, добро пожаловать в S.O. Вам нужно выполнить итерацию по вашей строке, @Gardener задает вам отличный вопрос, есть причина не использовать std::string ?? если нет, то вам действительно следует его использовать.

Ответ №1:

Я бы использовал std::string для хранения строки и извлек выгоду из std::vector и const_iterator для лучшего использования возможностей C :

 #include <string>
#include <vector>

int main()
{
  std::string s("This problem is too easy for me. I am an amazing programmer. Do you agree?");
  const char delim = ' ';
  std::vector<std::string> v;
  std::string tmp;

  for(std::string::const_iterator i = s.begin(); i <= s.end();   i)
  {
    if(*i != delim amp;amp; i != s.end())
    {
      tmp  = *i;
    }else
    {
      v.push_back(tmp);
      tmp = ""; 
    }
  }

  for(std::vector<std::string>::const_iterator it = v.begin(); it != v.end();   it) 
  {
    std::string str = *it,b;
    for(int i=str.size()-1;i>=0;i--)
      b =str[i];
    std::cout << b << " ";
  }

  std::cout << std::endl;
}
  

Вывод:

Почему я не могу использовать rof .em я ма на gnizama .remmargorp как ты?eerga

Комментарии:

1. Спасибо за всю помощь. Вы знаете, как исправить, где стоит пунктуация, она немного не в том месте.

Ответ №2:

Представленный вами код гораздо больше похож на что-то из C, а не из C . Не уверен, знакомы ли вы с вызовами std::string и функций. Поскольку код, который вы написали, довольно сложный, я предположу, что вы.

Вот пример того, как использовать fstream. Я почти всегда использую getline для ввода, потому что я нахожу, что это доставляет мне меньше проблем.

Затем я почти всегда использую stringstream для синтаксического анализа строки, потому что он аккуратно разделяет строки через каждый пробел.

Наконец, я пытаюсь вычислить while() или выполнить цикл{}while();, который запустит ввод из вызова getline().

Обратите внимание, что если слово заканчивается символом препинания, чтобы сохранить пунктуацию в конце, функция reverse_word () должна искать не-альфа-символы в конце, а затем сохранять их в стороне. Это можно было бы сделать, только поменяв местами прогоны букв.

 #include <iostream>
#include <fstream>
#include <string>
#include <sstream>

///////////////////
/// return true if ch is alpha
/// return false for digits, punctuation, and all else
bool is_letter(char ch){
  if((ch >= 'A' amp;amp; ch <= 'Z') ||
      (ch >= 'a' amp;amp; ch <= 'z')) {
    return true;
  } else {
    return false;
  }
}
////////
// Only reverse the letter portion of each word
//
std::string reverse_word(std::string str)
{
  std::string output_str; // Probably have to create a copy for output
  output_str.reserve(str.length()); // reserve size equal to input string

  // iterate through each letter of the string, backwards,
  // and copy the letters to the new string
  char save_non_alpha = 0;

  for (auto it = str.rbegin(); it != str.rend(); it  ) {
    /// If the last character is punctuation, then save it to paste on the end
    if(it == str.rbegin() amp;amp; !is_letter(*it)) {
      save_non_alpha = *it;
    } else {
      output_str  = *it;
    }
  }
  if(save_non_alpha != 0) {
    output_str  = save_non_alpha;
  }
  return output_str;  // send string back to caller
}

int main()
{
  std::string input_file_name{"input.txt"};
  std::string output_file_name{"output.txt"};
  std::string input_line;

  std::ifstream inFile;
  std::ofstream outFile;

  inFile.open(input_file_name, std::ios::in);
  outFile.open(output_file_name, std::ios::out);

  // if the file open failed, then exit
  if (!inFile.is_open() || !outFile.is_open()) {
    std::cout << "File " << input_file_name
        << " or file " << output_file_name
        << " could not be opened...exitingn";
    return -1;
  }


  while (std::getline(inFile, input_line)) {
    std::string word;
    std::string sentence;

    std::stringstream stream(input_line);

    // I just like stringstreams.  Process the input_line
    // as a series of words from stringstream.  Stringstream
    // will split on whitespace.  Punctuation will be reversed with the
    // word that it is touching
    while (stream >> word) {
      if(!sentence.empty())  // add a space before all but the first word
        sentence  = " ";
      word = reverse_word(word);
      sentence  = word;
    }
    outFile << sentence << std::endl;

  }
  inFile.close();
  outFile.close();
  return 0;
}
  

Комментарии:

1. Большое вам спасибо, это было чрезвычайно полезно! Единственная проблема, с которой я сталкиваюсь, заключается в том, что в выходных данных знаки препинания немного не в том месте.

2. Итак, вы хотите, чтобы знаки препинания действовали как разделитель или сортировались по концу слова. Я думаю, было бы проще расставить знаки препинания в конце слова, но это можно сделать любым способом.

3. Да, чтобы отсортировать конечную причину для примера: почему melborp si oot ysae rof .em Я ма на gnizama .remmargorp один из вас? конечно, это должно быть: sihT melborp si oot ysae rof em. Я ма на гнизаму реммаргорп. Что за ерга?

4. Вы понимаете вызов итератора rbegin ()? Если да, пожалуйста, примите ответ.

5. Еще один вопрос, возможно ли выполнить эту программу без использования ‘auto’?