有时生活会很轻松。通过使用现代 C++ 元素,最终实现将非常简单。
我不太确定我应该为 3 行代码解释什么。用代码中的cmets基本可见。
请看第一个解决方案:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cctype>
int main() {
// Open the input file and check, if it could be opened
if (std::ifstream inputStream{ "r:\\input.txt" }; inputStream) {
// Define a vector and read all words from the file
std::vector words(std::istream_iterator<std::string>(inputStream), {});
// Show result to the user
std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
}
然后下一个解决方案将单词转换为小写。所以,我不得不写 4 个陈述。请参阅下面的第二个解决方案。
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cctype>
int main() {
// Open the input file and check, if it could be opened
if (std::ifstream inputStream{ "r:\\input.txt" }; inputStream) {
std::vector<std::string> words{};
// Read all words from the file and convert to lower case
std::transform(std::istream_iterator<std::string>(inputStream), {}, std::back_inserter(words),
[](std::string w) { for (char& c : w) c = std::tolower(c); return w; });
// Show result to the user
std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
}
如果不需要存储数据,我们可以提出一个 2-statement 版本。
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <iterator>
#include <cctype>
int main() {
// Open the input file and check, if it could be opened
if (std::ifstream inputStream{ "r:\\input.txt" }; inputStream) {
// Read all words from the file and convert to lower case and output it
std::transform(std::istream_iterator<std::string>(inputStream), {}, std::ostream_iterator<std::string>(std::cout, "\n"),
[](std::string w) { for (char& c : w) c = std::tolower(c); return w; });
}
}
有时老师希望学生使用指针学习动态内存管理。
但强烈建议不要使用拥有内存的指针。十多年前,std::vector 就是出于这个原因发明的。
无论如何,我也会展示一个使用new 的解决方案。它有效,但你不应该使用它。
int main() {
// Open the input file and check, if it could be opened
if (std::ifstream inputStream{ "r:\\input.txt" }; inputStream) {
// Do some initial allocation of memory
std::string* words = new std::string[1]{};
unsigned int numberOfAvaliableSlotsInDynamicArray{1};
// Now we want to read words. We want also to count the words,so that we can allocate appropriate memory
std::string word{};
unsigned int wordCounter{};
// Read all words in a loop
while (inputStream >> word) {
// Check, if we still have enough space in our dynamic array
if (wordCounter >= numberOfAvaliableSlotsInDynamicArray) {
// Oh, we are running out of space. Get more memory
numberOfAvaliableSlotsInDynamicArray *= 2;
std::string* temp = new std::string[numberOfAvaliableSlotsInDynamicArray]{};
// Copy all existing data into new array
for (unsigned int i{}; i < wordCounter; ++i)
temp[i] = words[i];
// Delete old memory
delete[] words;
// And assign new storage to words
words = temp;
}
// STore the recently read word at the end of the array
words[wordCounter] = word;
// Count words. Now we have one word more
++wordCounter;
}
// Now we have read all words from the file. Show output
for (unsigned int i{}; i < wordCounter; ++i)
std::cout << words[i] << '\n';
// Release memory
delete[] words;
}
}
即使是智能指针(如果有的话也应该用作指针)也不好。
也不应该使用以下内容。
#include <iostream>
#include <fstream>
#include <string>
#include <memory>
int main() {
// Open the input file and check, if it could be opened
if (std::ifstream inputStream{ "r:\\input.txt" }; inputStream) {
// Do some initial allocation of memory
std::unique_ptr<std::string[]> words = std::unique_ptr<std::string[]>(new std::string[1]);
unsigned int numberOfAvaliableSlotsInDynamicArray{ 1 };
// Now we want to read words. We want also to count the words,so that we can allocate appropriate memory
std::string word{};
unsigned int wordCounter{};
// Read all words in a loop
while (inputStream >> word) {
// Check, if we still have enough space in our dynamic array
if (wordCounter >= numberOfAvaliableSlotsInDynamicArray) {
// Oh, we are running out of space. Get more memory
numberOfAvaliableSlotsInDynamicArray *= 2;
std::unique_ptr<std::string[]> temp = std::unique_ptr<std::string[]>(new std::string[numberOfAvaliableSlotsInDynamicArray]);
// Copy all existing data into new array
for (unsigned int i{}; i < wordCounter; ++i)
temp[i] = std::move(words[i]);
// And assign new storage to words
words = std::move(temp);
}
// STore the recently read word at the end of the array
words[wordCounter] = word;
// Count words. Now we have one word more
++wordCounter;
}
// Now we have read all words from the file. Show output
for (unsigned int i{}; i < wordCounter; ++i)
std::cout << words[i] << '\n';
}
}
结论:使用std::vector。