gpt4 book ai didi

c++ - 使用指针重新复制字符数组并修剪前导空格

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:53 26 4
gpt4 key购买 nike

我正在自学 C++ 并正在研究这个问题:

Write a function named trimfrnt() that deletes all leading blanks from a string. Write the function using pointers with the return type void.

下面是我对这个问题的尝试,我尝试用两种方法解决这个问题(你可以看到我的两个函数 trimfrnt1()trimfrnt2() trimfrnt1() 工作正常。我有点意外地得到了这个工作。在我编码之后,我不确定它为什么会工作。我的困惑在于 for 循环。我在下面绘制了 msg 数组的图表:

             |<--ptrMsg--------->|
|<------for loop---->|
0 1 2 3 4 5 6 7
+----+----+----+----+----+----+----+----+
| | | G | R | E | A | T | \0 |
+----+----+----+----+----+----+----+----+
| G | R | E | A | T | | | \0 |
+----+----+----+----+----+----+----+----+

问题一

根据我的上图,由于重叠,我实际上期待的是文本:“GREATAT”。因为我只循环了 5 个字母,所以整个字符串如何移动并重新初始化?

问题2

问题说明要使用指针,所以我认为 trimfrnt1 是作弊,因为我正在编制索引,所以我尝试使用 trimfrnt2 的另一种方法。这个函数我卡在了 while 循环中:

    // shift characters to beginning of char array
while( *(ptrMsg + count) != '\0' )
{
*ptrMsg = *(ptrMsg + count);
ptrMsg++;
count++;
}

这部分代码对我不起作用。当我打印出 *(ptrMsg + count) 时,我得到了正确的字符,但是当我将它分配给 *ptrMsg 的内容时,我得到了乱码。在这种情况下,我也期待“GREATAT”,因为我没有重新初始化剩余的字符。有没有办法像我尝试的那样使用指针方法来做到这一点?

谢谢!

#include<iostream>
#include<iomanip>

using namespace std;

void trimfrnt1(char msg[], int size)
{
char *ptrMsg = msg;

// Find beginning of text
while(*ptrMsg == ' ')
ptrMsg++;

// Copy text to beginning of array
for(int i=0; i < size; i++)
msg[i] = *ptrMsg++;

// Reset pointer to beginning of array
ptrMsg = msg;

// Print array
cout << "new msg1: ";
cout << "\"" << ptrMsg << "\"" << endl;
cout << endl;

return;
}

void trimfrnt2(char msg[], int size)
{
int count = 0; // used to find leading non-white space
char *ptrMsg = msg; // pointer to character array

// find first place of non white space
while( *(ptrMsg + count) == ' ')
count++;

cout << "count = " << count << endl;

// shift characters to beginning of char array
while( *(ptrMsg + count) != '\0' )
{
*ptrMsg = *(ptrMsg + count);
ptrMsg++;
count++;
}
cout << "count = " << count << endl;

// Reset pointer to beginning of array
ptrMsg = msg;

// Print array
cout << "new msg2: ";
cout << "\"" << ptrMsg << "\"" << endl;
cout << endl;
}


int main()
{
char msg[] = " GREAT";
const int size = sizeof(msg)/sizeof(char);

cout << "Orginal msg:\"" << msg << "\"" << endl;

trimfrnt1(msg, size);

return 0;
}

最佳答案

trimfrnt1() 具有未定义的行为 - 您的 for 循环导致 ptrMsg 超出数组范围,因此您读取的内存不'属于你,任何事情都可能发生。似乎在您的平台上,这样的读取是可以的,因此循环愉快地从内存中复制“随机”垃圾 - 但在此之前,它复制终止 NUL 字符,因此您无法获取 结果是“GREATAT”。您应该像这样更改 while 循环:

while(*ptrMsg == ' ')
{
ptrMsg++;
--size;
}

这仍然会给你 "GREAT",因为终止 NULsizeof 结果的一部分。

trimfrnt2() 中,您的循环是错误的,因为您正在递增 count,这是不应该的。这就是为什么最好给变量取一个真正具有描述性的名称。如果它是在其语义之后调用的(例如 numberOfSpaces),您甚至不会考虑在复制 while() 循环中写入增量。如果您删除该增量,trimfrnt2() 应该会为您提供您期望的 "GREATAT" 结果。


为了获得灵感,下面是我如何使用不带算术的指针来实现它:

void trimfrnt3(char *msg, size_t size)
{
const char *src = msg;
while (*src == ' ')
++src;
char *dst = msg;
while (*src)
{
*dst = *src;
++src;
++dst;
}
cout << "new msg: \"" << msg << "\"\n"; //don't use endl unless you want to flush immediately
}

如您所见,此版本甚至不使用 size 参数,因此可以将其删除。

关于c++ - 使用指针重新复制字符数组并修剪前导空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19978890/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com