英文:
Removing first word using pointers from char array(C++)
问题
I need to write a program to remove the first word from a char array (char []) using only pointers. If there are multiple blank spaces in front, I have to ignore them and remove the first word.
These are the loops I used:
#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
is a pointer to a character array (char *p = char int[1000]
).
When I output the char array later to see if the program is working, it doesn't work properly if the array was an empty array or a one-word array.
Why does *p
(pointer to character) print out random signs (chars) instead of nothing when the array is blank?
Example:
Input: word
Output: #U
Full program instead of just loops for editing the array.
英文:
I need to write a program to remove the first word from a char array (char []) using only pointers. If there are multiple blank spaces in front, I have to ignore them and remove the first word.
These are the loops I used:
#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 is a pointer to char[] (char *p=char int[1000])
When I output the char array later to see if the program is working, it doesn't work properly if the array was an empty array or a one-word array.
Why does *p (pointer to character) print out random signs (chars) instead of nothing, when the array is blank?
Example:
Input: word
Output: #U
Full program instead of just loops for editing the array.
答案1
得分: 2
Your 1st and 2nd while
loops don't stop if the null terminator '\0'
is reached. So, when the array is empty or contains only 1 word, you are advancing p
past the null terminator into an uninitialized section of the array, and possibly even beyond the end of the array into surrounding memory.
Also, you should not be doing p++
inside the 1st loop's condition like you are doing. Your 1st loop is advancing p
by two characters per iteration when *p
is a space character. It should be advancing p
by only one character per iteration.
Try this instead:
#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 != '#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;
}
') {
++p;
}
// skip 1st word
while (*p > ' ') {
++p;
}
// skip whitespace between 1st and 2nd words
while (*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;
}
') {
++p;
}
std::cout << "Sentence without first word: ";
while (*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;
}
') {
std::cout << *p;
++p;
}
// or simply:
// std::cout << p;
std::cout << std::endl;
return 0;
}
英文:
Your 1st and 2nd while
loops don't stop if the null terminator '\0'
is reached. So, when the array is empty or contains only 1 word, you are advancing p
past the null terminator into an uninitialized section of the array, and possibly even beyond the end of the array into surrounding memory.
Also, you should not be doing p++
inside the 1st loop's condition like you are doing. Your 1st loop is advancing p
by two characters per iteration when *p
is a space character. It should be advancing p
by only one character per iteration.
Try this instead:
#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 != '#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;
}
') {
++p;
}
// skip 1st word
while (*p > ' ') {
++p;
}
// skip whitespace between 1st and 2nd words
while (*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;
}
') {
++p;
}
std::cout << "Sentence without first word: ";
while (*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;
}
') {
std::cout << *p;
++p;
}
// or simply:
// std::cout << p;
std::cout << std::endl;
return 0;
}
答案2
得分: 1
while (*p != ' ')
字符串的末尾由一个 '\0'
字节标记。这个字节不是空格。因此,这个while循环会继续前进,寻找一个不存在的空格,导致未定义的行为。这是计算机编程黄金法则的一个例子:「你的计算机总是按照你告诉它做的事情来做,而不是你想让它做的事情。」你告诉你的计算机,在看到 '\0'
之前不要停止while循环。所以你的计算机会执行这个任务。你需要在这里检查空格和 '\0'
。
<details>
<summary>英文:</summary>
while(*p!=' ')
The end of a character string is marked by a '`The end of a character string is marked by a '`\0'` byte.
Which is not a space.
So, this while loop will happily plow forward, looking for a nonexistent space, resulting in undefined behavior.
This is an example of the Golden Rule Of Computer Programming in force: "Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do". You told your computer to not stop the while loop until it sees a `' '`. So that's what your computer does. The end of the string will not stop your computer, from this mission.
You need to check for both the space and a `'\0'`, here.
</details>
# 答案3
**得分**: 1
这是一个关于C语言的问题,而不是C++问题,重要的是要记住,“传统”的C字符串以`'\0'`字节结尾。未能检查这一点会导致各种内存访问错误。
这是一个快速、粗糙、不太规范的实现,它跳过了输入的每一行的第一个单词,同时正确地检查C字符串的结束字节。是否应该跳过第一个单词之后的空格(而不仅仅是第一个单词之前的空格),这很容易调整。
```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;
}
}
'` byte.
Which is not a space.
So, this while loop will happily plow forward, looking for a nonexistent space, resulting in undefined behavior.
This is an example of the Golden Rule Of Computer Programming in force: "Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do". You told your computer to not stop the while loop until it sees a `' '`. So that's what your computer does. The end of the string will not stop your computer, from this mission.
You need to check for both the space and a `'The end of a character string is marked by a '`\0'` byte.
Which is not a space.
So, this while loop will happily plow forward, looking for a nonexistent space, resulting in undefined behavior.
This is an example of the Golden Rule Of Computer Programming in force: "Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do". You told your computer to not stop the while loop until it sees a `' '`. So that's what your computer does. The end of the string will not stop your computer, from this mission.
You need to check for both the space and a `'\0'`, here.
</details>
# 答案3
**得分**: 1
这是一个关于C语言的问题,而不是C++问题,重要的是要记住,“传统”的C字符串以`'\0'`字节结尾。未能检查这一点会导致各种内存访问错误。
这是一个快速、粗糙、不太规范的实现,它跳过了输入的每一行的第一个单词,同时正确地检查C字符串的结束字节。是否应该跳过第一个单词之后的空格(而不仅仅是第一个单词之前的空格),这很容易调整。
```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;
}
}
'`, here.
</details>
# 答案3
**得分**: 1
这是一个关于C语言的问题,而不是C++问题,重要的是要记住,“传统”的C字符串以`'The end of a character string is marked by a '`\0'` byte.
Which is not a space.
So, this while loop will happily plow forward, looking for a nonexistent space, resulting in undefined behavior.
This is an example of the Golden Rule Of Computer Programming in force: "Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do". You told your computer to not stop the while loop until it sees a `' '`. So that's what your computer does. The end of the string will not stop your computer, from this mission.
You need to check for both the space and a `'\0'`, here.
</details>
# 答案3
**得分**: 1
这是一个关于C语言的问题,而不是C++问题,重要的是要记住,“传统”的C字符串以`'\0'`字节结尾。未能检查这一点会导致各种内存访问错误。
这是一个快速、粗糙、不太规范的实现,它跳过了输入的每一行的第一个单词,同时正确地检查C字符串的结束字节。是否应该跳过第一个单词之后的空格(而不仅仅是第一个单词之前的空格),这很容易调整。
```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;
}
}
'`字节结尾。未能检查这一点会导致各种内存访问错误。
这是一个快速、粗糙、不太规范的实现,它跳过了输入的每一行的第一个单词,同时正确地检查C字符串的结束字节。是否应该跳过第一个单词之后的空格(而不仅仅是第一个单词之前的空格),这很容易调整。
```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;
}
}
如果您需要进一步的信息或帮助,请告诉我。
英文:
Well, this is a C question, not a C++ question, and it is important to keep in mind that “traditional” C strings end with a '\0'
byte. Failing to check for that leads to all sorts of memory access errors.
Here’s a quick and dirty and sloppy implementation that skips the first word of each line on its input while checking for C-string ending bytes properly. Whether the spaces after the first word (and not only before the first word) should be skipped, that’s easy to adjust.
#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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论