有没有更好的方法来为C++写这个?
Is there a better way to write this for C++?
目标是通过提取用空格分隔的单词,从输入的字符串创建子字符串。
子字符串本身必须是变量。
听起来很容易,但困难的是你只能使用 strcpy、strcmp、strlen、strcat、strncpy、strncmp、strnlen 和 strncat。
例:
输入:
"John 40 Hitman"
司机:
...
cout << word1 << endl
<< word2 << endl
<< word3 << endl;
输出:
John
40
Hitman
这是我的代码
#include <iostream>
#include <cstring>
#include <stdio.h>
int main(){
const char *string = "Name Age Job";
char name[10];
char age[10];
char job[10];
int length = strlen(string);
int temp = 0;
bool flag = false;
for(int i = 0; i < length + 1; i++){
if(isspace(string[i]) && !flag){
strncpy(name, string, i);
name[i] = ' ';
temp = i;
flag = !flag;
cout << name << endl;
continue;
}
if(isspace(string[i])){
strncpy(age, string + temp + 1, length - i - 1);
age[temp - i] = ' ';
temp = i;
cout << age << endl;
continue;
}
if(string[i] == ' '){
strncpy(job, string + temp + 1, length);
job[temp - i] = ' ';
cout << job << endl;
}
}
它可以工作,但它必须使用标志布尔值,字符串不是动态的,仅适用于具有 2 个空格的字符串,并且有很多重复的代码。总的来说真的很卡顿,但我花了大约两个小时,我不知道如何改进它。
如果你想知道,这确实是一个家庭作业问题,但这是一个入门课,我的教授只想要只有 3 个单词的硬编码字符串的正确输出。但是,我想学习如何改进它,并且非常感谢任何帮助。谢谢。
您需要做的就是将空格' '
替换为' '
(字符串末尾(,从而从原始字符串创建 3 个子字符串。下面的程序这样做,只是将字符串转储到cout
但您也可以将指针保存在数组中(例如。 char* substring[3]
(。
int main(){
char string[] = "Name Age Job";
char* temp = string;
for(char* it = string; *it; ++it ) {
if (*it == ' ') {
*it = ' ';
std::cout << temp << std::endl;
temp= it + 1;
}
}
std::cout << temp << std::endl;
}
C 函数执行此操作的正确方法是使用 strtok
,尽管它会就地切碎一个字符串。
关于你的代码,有很多不必要的分支和检查。你应该避免continue
,这是一个几乎 100% 确定的循环需要改进的迹象。每当您发现自己需要它时,通常都有更好的方法。
您还应该避免strncpy
因为正如您所注意到的,跟踪何时终止 null 以及何时不终止是一种痛苦。这是一个危险的函数,比memcpy
慢得多,可以在这里使用。
这是一个基于使用 2 个指针的简化版本,一个始终设置为指向下一个空格,另一个始终设置为指向下一个有效单词的开头。
#include <string.h>
#include <ctype.h>
#include <stdio.h>
const char* find_next_space (const char* str)
{
while(*str != ' ' && !isspace(*str))
str++;
return str;
}
int main (void)
{
const char str[] = "hello world how are you";
char substr[5][10];
const char* word_start = str;
for(size_t i = 0; i<5; i++)
{
if(*word_start == ' ')
break;
const char* next_space = find_next_space(word_start);
size_t length = (size_t)(next_space-word_start);
memcpy(substr[i], word_start, length);
substr[i][length] = ' ';
puts(substr[i]);
word_start = next_space+1;
}
}
此代码通过不检查字符串是否合适并且不分配内存来简化事情。真正的生产质量 C 代码不会使用char [5][10]
而是使用指针数组char* [5]
其中每个指针都设置为指向动态分配的内存。
我同意@acraig5075,因为你的代码比C++更C。 如果您正在考虑使用 STL 字符串以C++编写此内容,则一种方法如下。
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
std::vector<std::string> split_string( const std::string &srcString, const char &delimiterKeywrd )
{
/**
* Splits a string according to a keyword delimiter and returns a vector with the
* segments of the split string.
*
* Args:
* @param srcString: The required string to split.
* @param delimiterKeywrd: The delimiter keyword that the string will be splitted to
* @return segmentsVectr: A vector holding the segments of the srcString that was splitted.
*
*/
std::stringstream inputStr;
inputStr.str( srcString );
std::string segment;
std::vector<std::string> segmentsVectr;
while( std::getline( inputStr, segment, delimiterKeywrd ) )
{
segmentsVectr.push_back( segment );
}
return segmentsVectr;
}
int main() {
std::string inputStr{"John 40 Hitman"};
std::vector<std::string> result;
char delimiterKeywrd = ' ';
result = split_string( inputStr, delimiterKeywrd );
// Iterate through the vector and print items on a different line.
for ( const std::string &item : result )
{
std::cout << item << std::endl;
}
return 0;
}
检查 std::string 在 cpp首选项和示例,如果你不熟悉。 同样在这里,我正在使用std::stringstream,这使得使用std::getline变得容易。
如果 std::stringstream 不是您的首选方式,您可以随时从另一个关于按字符拆分字符串的问题中检查此实现。
希望这有帮助。
- C++:将控制台输出存储在宏中更好吗
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 初始化具有非默认构造函数的std::数组项的更好方法
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 为什么新的随机库比std::rand()更好
- 寻找一种更好的方法来表示无符号字符数组
- 哪种方法更好,性能明智
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 什么是更好的做法?通过指针或标识符传递类成员?
- 寻求更好地理解标准::访问
- 线程消息传递或更好:在"大师班"中访问其他班级的成员
- 有没有更好的方法来处理异常? try-catch块真的很丑
- 如何更好地检查两个 char 变量是否在一组值中?
- 有没有更好的方法对C++中的三个整数进行排序?
- 什么模板用法在阶乘中更好
- 平面缓冲区可以利用向量中的 0 吗?还是其他小波比哈尔变换更好?
- 我们应该如何使用枚举类进行索引(或者我们应该更好地避免这种情况)?
- Protobuf中重复字段的问题.使用重复字段进行序列化/反序列化的更好方法是什么?
- 比使用 s.str().c_str() 更好的表达?
- 测量时间以在 c++ 中生成更好的随机数