c++ - C++ C-string(显然)没有要显示的内容
问题描述
首先,我对编程和 Stack Overflow 都是新手。
我正在自学 Schaum 的 C++ 编程大纲,我对问题 8.24 有一些问题(书中几乎所有问题都给出了解决方案,但我想知道为什么我的代码特别不能按预期工作)。
应该给你一个 c 字符串并返回给定的字符串,但它的所有标记都以相反的顺序排列(但保持标记本身的自然顺序)。也就是说,给定“Enter a sentence”,它会在屏幕上显示“sentence a Enter”。
我的代码如下:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char line1[100];
cout << "Enter a sentence (enter \".\" to terminate input):\n";
cin.getline(line1,100,'.');
char line2[strlen(line1) + 1]; // we add 1 for the empty char that ends every c string
int char_count = strlen(line1); //strlen() does not include the empty char
char* p = strtok(line1," ");
while (p)
{
char_count -= strlen(p); // we substract p's len to start adding its chars
for (int i = 0; i <= strlen(p); i++)
line2[char_count + i] = p[i]; // we then add the chars themselves
if ((char_count - 1) > 0)
line2[--char_count] = ' '; // a blanck space is needed between the different tokens
p = strtok(NULL, " ");
}
cout << "\n" << line2 << "\n";
}
解决方案
不幸的是,代码在很多方面都是错误的。最明显的是单词反转过程的模糊性(以及它与单词迭代混合的事实)。
根据评论者的说法,您没有使用 C++。在 C++ 中,这将是相当简单的:
#include <algorithm>
#include <iostream>
#include <string>
void reverse_words(std::string& s) {
/* starting position of the word */
size_t last_pos = 0;
do {
/* find the end of current word */
size_t end_pos = std::min( s.find(' ', last_pos + 1), s.size() );
/* reverse one word inplace */
std::reverse(s.begin() + last_pos, s.begin() + end_pos);
/* advance to the begining of the next word */
last_pos = end_pos + 1;
} while (pos != std::string::npos);
std::reverse(s.begin(), s.end());
}
int main()
{
std::string s = "This is a sentence";
reverse_words(s);
std::cout << s << std::endl;
}
希望你能看到该方法的精髓:依次查找每个单词的开头和结尾,反转该单词中的字母顺序,最后反转整个字符串。
现在,回到 C 字符串问题。您可以将std::string::find
call替换为strtok
并编写您的std::reverse
专门用于 C 字符串的版本(整个字符串或其部分的反转比反转单词顺序更简单,这也是推荐的练习)。
从一个更简单的程序开始,该程序使用strtok
. 然后编写一个reverse
程序并对其进行测试。最后,将这个词迭代与reverse
. 我个人认为这是确保您的实现正确的唯一方法 - 确保每个部分都能够单独测试每个部分。
推荐阅读
- javascript - React-router Prompt:我如何真正覆盖浏览器确认对话框的取消行为?
- javascript - 在 vue js 中 axios 调用后如何更新头部标题
- flutter - 如何为 Flutter UI 创建聊天消息气泡
- kubernetes - hazelcast-kubernetes 在 java 11 中启用了集群 ClassNotFoundException
- python - 如何遍历两个不同长度的列表,然后仅将那些不相似的值保存在新列表中
- javascript - 如何将多个 ID 添加到 discord.js 检查?
- java - 如何将自定义 setContent 方法添加到 Spring Content
- java - 无法识别简单的代码方法(Intent、finish() 等)
- r - 用R中的分组和条件根据条件替换一行中的负值
- c# - 为什么在 MRTK for Unity 中为 TouchHandler 中的事件分配操作失败?