使用指针从 char 数组中删除第一个单词(C++)

问题描述 投票:0回答:3

我需要编写一个程序,仅使用指针从 char 数组 (char []) 中删除第一个单词。如果前面有多个空格,我必须忽略它们并删除第一个单词。

这些是我使用的循环:

#include <iostream>
#include <cmath>

int main()
{
    char sentence[1000];
    std::cout<<"Input sentence: ";
    std::cin.getline(sentence,1000);
    char *p=sentence;
    while(*p==' ' && *p++==' ')
    {
        p++;
    }
    while(*p!=' ')
    {
        p++;
    }
    std::cout<<"Sentence without first word: ";
    while(*p!=0)
    {
        std::cout<<*p;
        p++;
    }
    std::cout<<std::endl;
    return 0;
}

*p 是指向 char[] 的指针 (char *p=char int[1000])

我后面输出char数组看程序是否运行时,如果数组是空数组或单字数组,则无法正常运行。

当数组为空时,为什么 *p(指向字符的指针)打印出随机符号(字符)而不是什么都不打印?

例子:

Input:       word

Output: #U

完整的程序,而不仅仅是用于编辑数组的循环。

c++ arrays pointers char
3个回答
2
投票

如果达到空终止符

while
,您的第一个和第二个
'\0'
循环不会停止。因此,当数组为空或仅包含 1 个单词时,您将
p
通过空终止符进入数组的未初始化部分,甚至可能超出数组末尾进入周围内存。

另外,你不应该像你正在做的那样在第一个循环的条件下做

p++
。当
p
是空格字符时,您的第一个循环每次迭代将
*p
推进两个字符。它应该每次迭代仅将
p
推进一个字符。

试试这个:

#include <iostream>

int main()
{
    char sentence[1000] = {};
    std::cout << "Input sentence: ";
    std::cin.getline(sentence, 1000);

    char *p = sentence;

    // skip leading whitespace before 1st word
    while (*p <= ' ' && *p != '\0') {
        ++p;
    }

    // skip 1st word
    while (*p > ' ') {
        ++p;
    }

    // skip whitespace between 1st and 2nd words
    while (*p <= ' ' && *p != '\0') {
        ++p;
    }

    std::cout << "Sentence without first word: ";
    while (*p != '\0') {
        std::cout << *p;
        ++p;
    }
    // or simply:
    // std::cout << p;

    std::cout << std::endl;
    return 0;
}

1
投票
while(*p!=' ')

字符串的结尾用'

\0'
字节标记。

这不是空格。

所以,这个 while 循环会愉快地向前推进,寻找一个不存在的空间,导致未定义的行为。

这是有效的计算机编程黄金法则的一个例子:“你的计算机总是完全按照你告诉它做的而不是你想要它做的”。你告诉你的计算机在看到

' '
之前不要停止 while 循环。这就是您的计算机所做的。字符串的结尾不会停止你的计算机,从这个任务开始。

您需要在此处检查空格和

'\0'


0
投票

嗯,这是一个 C 问题,而不是 C++ 问题,重要的是要记住“传统的”C 字符串以

'\0'
字节结尾。未能检查会导致各种内存访问错误。

这是一个快速、肮脏和草率的实现,它跳过输入中每一行的第一个单词,同时正确检查 C 字符串结束字节。第一个单词之后的空格(不仅是第一个单词之前)是否应该跳过,这很容易调整。

#include <iostream>
#include <string>

namespace {
const char* skip_first_word_c_style(const char* c_str) {
  while (*c_str && *c_str == ' ') ++c_str;  // spaces before first word
  while (*c_str && *c_str != ' ') ++c_str;  // first word
  while (*c_str && *c_str == ' ') ++c_str;  // spaces after first word
  return c_str;
}
}  // namespace

int main() {
  std::string line;
  while (std::getline(std::cin, line)) {
    std::cout << skip_first_word_c_style(line.c_str()) << std::endl;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.