c – 使用指针和修剪前导空格重用字符数组

前端之家收集整理的这篇文章主要介绍了c – 使用指针和修剪前导空格重用字符数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在学习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 |                             
+----+----+----+----+----+----+----+----+

问题1

从我上面的图表中,我实际上期待文本:“GREATAT”因为重叠.整个字符串是如何移位和重新初始化的,因为我只通过5个字母循环?

问题2

问题陈述使用指针,所以我虽然trimfrnt1作弊,因为我索引所以我试图做另一种trimfrnt2方法.这个函数我被困在while循环中:

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

这部分代码对我不起作用.当我打印出*(ptrMsg计数)时,我得到正确的字符,但是当我将它分配给* 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()具有未定义的行为 – 你为循环导致ptrMsg超出数组,因此你正在读取不属于你的内存,任何事情都可能发生.似乎在你的平台上,这样的读取是正常的,所以循环愉快地从内存中复制“随机垃圾 – 但在此之前,它复制终止NUL字符,因此你不能得到“GREATAT”.您应该像这样更改while循环:
while(*ptrMsg == ' ')
{
  ptrMsg++;
  --size;
}

这仍然会给你“伟大”,因为终止NUL是结果大小的一部分.

在trimfrnt2()中,你的循环是错误的,因为你递增计数,你不应该这样.这就是为变量提供真正描述性名称的原因.如果它在语义之后被调用(例如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&C++相关文章