我需要编写一个程序,仅使用指针从 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
完整的程序,而不仅仅是用于编辑数组的循环。
如果达到空终止符
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;
}
while(*p!=' ')
字符串的结尾用'
\0'
字节标记。
这不是空格。
所以,这个 while 循环会愉快地向前推进,寻找一个不存在的空间,导致未定义的行为。
这是有效的计算机编程黄金法则的一个例子:“你的计算机总是完全按照你告诉它做的而不是你想要它做的”。你告诉你的计算机在看到
' '
之前不要停止 while 循环。这就是您的计算机所做的。字符串的结尾不会停止你的计算机,从这个任务开始。
您需要在此处检查空格和
'\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;
}
}