Removing first word using pointers from char array(C++)

huangapple go评论58阅读模式
英文:

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 &lt;iostream&gt;
#include &lt;cmath&gt;

int main()
{
    char sentence[1000];
    std::cout&lt;&lt;&quot;Input sentence: &quot;;
    std::cin.getline(sentence,1000);
    char *p=sentence;
    while(*p==&#39; &#39; &amp;&amp; *p++==&#39; &#39;)
    {
        p++;
    }
    while(*p!=&#39; &#39;)
    {
        p++;
    }
    std::cout&lt;&lt;&quot;Sentence without first word: &quot;;
    while(*p!=0)
    {
        std::cout&lt;&lt;*p;
        p++;
    }
    std::cout&lt;&lt;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 &#39;\0&#39; 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 &lt;iostream&gt;

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

    char *p = sentence;

    // skip leading whitespace before 1st word
    while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;
#include &lt;iostream&gt;
int main()
{
char sentence[1000] = {};
std::cout &lt;&lt; &quot;Input sentence: &quot;;
std::cin.getline(sentence, 1000);
char *p = sentence;
// skip leading whitespace before 1st word
while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;\0&#39;) {
++p;
}
// skip 1st word
while (*p &gt; &#39; &#39;) {
++p;
}
// skip whitespace between 1st and 2nd words
while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;\0&#39;) {
++p;
}
std::cout &lt;&lt; &quot;Sentence without first word: &quot;;
while (*p != &#39;\0&#39;) {
std::cout &lt;&lt; *p;
++p;
}
// or simply:
// std::cout &lt;&lt; p;
std::cout &lt;&lt; std::endl;
return 0;
}
&#39;) { ++p; } // skip 1st word while (*p &gt; &#39; &#39;) { ++p; } // skip whitespace between 1st and 2nd words while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;
#include &lt;iostream&gt;
int main()
{
char sentence[1000] = {};
std::cout &lt;&lt; &quot;Input sentence: &quot;;
std::cin.getline(sentence, 1000);
char *p = sentence;
// skip leading whitespace before 1st word
while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;\0&#39;) {
++p;
}
// skip 1st word
while (*p &gt; &#39; &#39;) {
++p;
}
// skip whitespace between 1st and 2nd words
while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;\0&#39;) {
++p;
}
std::cout &lt;&lt; &quot;Sentence without first word: &quot;;
while (*p != &#39;\0&#39;) {
std::cout &lt;&lt; *p;
++p;
}
// or simply:
// std::cout &lt;&lt; p;
std::cout &lt;&lt; std::endl;
return 0;
}
&#39;) { ++p; } std::cout &lt;&lt; &quot;Sentence without first word: &quot;; while (*p != &#39;
#include &lt;iostream&gt;
int main()
{
char sentence[1000] = {};
std::cout &lt;&lt; &quot;Input sentence: &quot;;
std::cin.getline(sentence, 1000);
char *p = sentence;
// skip leading whitespace before 1st word
while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;\0&#39;) {
++p;
}
// skip 1st word
while (*p &gt; &#39; &#39;) {
++p;
}
// skip whitespace between 1st and 2nd words
while (*p &lt;= &#39; &#39; &amp;&amp; *p != &#39;\0&#39;) {
++p;
}
std::cout &lt;&lt; &quot;Sentence without first word: &quot;;
while (*p != &#39;\0&#39;) {
std::cout &lt;&lt; *p;
++p;
}
// or simply:
// std::cout &lt;&lt; p;
std::cout &lt;&lt; std::endl;
return 0;
}
&#39;) { std::cout &lt;&lt; *p; ++p; } // or simply: // std::cout &lt;&lt; p; std::cout &lt;&lt; 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 &#39;`
The end of a character string is marked by a &#39;`\0&#39;` 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: &quot;Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do&quot;. You told your computer to not stop the while loop until it sees a `&#39; &#39;`. So that&#39;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 `&#39;\0&#39;`, 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;
}
}
&#39;` 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: &quot;Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do&quot;. You told your computer to not stop the while loop until it sees a `&#39; &#39;`. So that&#39;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 `&#39;
The end of a character string is marked by a &#39;`\0&#39;` 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: &quot;Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do&quot;. You told your computer to not stop the while loop until it sees a `&#39; &#39;`. So that&#39;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 `&#39;\0&#39;`, 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;
}
}
&#39;`, here. </details> # 答案3 **得分**: 1 这是一个关于C语言的问题,而不是C++问题,重要的是要记住,“传统”的C字符串以`'
The end of a character string is marked by a &#39;`\0&#39;` 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: &quot;Your Computer Always Does Exactly What You Tell It To Do Instead Of What You Want It To Do&quot;. You told your computer to not stop the while loop until it sees a `&#39; &#39;`. So that&#39;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 `&#39;\0&#39;`, 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 &#39;\0&#39; 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 &lt;iostream&gt;
#include &lt;string&gt;

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

int main() {
  std::string line;
  while (std::getline(std::cin, line)) {
    std::cout &lt;&lt; skip_first_word_c_style(line.c_str()) &lt;&lt; std::endl;
  }
}

huangapple
  • 本文由 发表于 2023年4月13日 20:54:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76005690.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定