有没有更好的方法为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] = '\0';
    temp = i;
    flag = !flag;
    cout << name << endl;
    continue;
  }
  if(isspace(string[i])){
    strncpy(age,string + temp + 1,length - i - 1);
    age[temp - i] = '\0';
    temp = i;
    cout << age << endl;
    continue;
  }
  if(string[i] == '\0'){
    strncpy(job,length);
    job[temp - i] = '\0';
    cout << job << endl;
  }
}

它可以工作,但是必须使用标志布尔值,字符串不是动态的,仅适用于具有2个空格的字符串,并且有很多重复的代码。总体而言,它确实很简陋,但我为此花了大约两个小时,而且我不知道如何改善它。

如果您想知道,这确实是一个家庭作业问题,但这是一个入门班,我的教授只想为只有3个单词的硬编码字符串提供正确的输出。但是,我想学习如何改进它,并非常感谢您的帮助。谢谢。

mfj111071 回答:有没有更好的方法为C ++编写此代码?

所有您需要做的就是用' '(字符串结尾)替换空间'\0',从而从原始字符串创建3个子字符串。以下程序会执行此操作,只是将字符串转储到cout,但您也可以将指针保存在数组中(例如char* substring[3])。

int main(){
    char string[] = "Name Age Job";
    char* temp = string;
    for(char* it = string; *it; ++it ) {
        if (*it == ' ') {
            *it = '\0';
            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 != '\0' && !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 == '\0')
      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] = '\0';
    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;
}

如果不熟悉,请在cppreference和示例中查看std::string。 同样在这里,我正在使用std::stringstream,这使得使用std::getline很容易。

如果std :: stringstream不是您的首选方式,则可以始终从另一个有关按字符拆分字符串的问题中检查this的实现。

希望这会有所帮助。

本文链接:https://www.f2er.com/3052686.html

大家都在问