c – 使用指针和修剪前导空格重用字符数组
我正在学习C并且正在研究这个问题:
我对这个问题的尝试在下面,我尝试了两种方法来解决这个问题(你可以看到我的两个函数trimfrnt1()和trimfrnt2().trimfrnt1()工作正常.我有点意外地工作.我编码之后,我不确定为什么它确实有效.我的困惑是在for循环.我画了一个msg数组的图表如下: |<--ptrMsg--------->| |<------for loop---->| 0 1 2 3 4 5 6 7 +----+----+----+----+----+----+----+----+ | | | G | R | E | A | T | | +----+----+----+----+----+----+----+----+ | G | R | E | A | T | | | | +----+----+----+----+----+----+----+----+ 问题1 从我上面的图表中,我实际上期待文本:“GREATAT”因为重叠.整个字符串是如何移位和重新初始化的,因为我只通过5个字母循环? 问题2 问题陈述使用指针,所以我虽然trimfrnt1作弊,因为我索引所以我试图做另一种trimfrnt2方法.这个函数我被困在while循环中: // shift characters to beginning of char array while( *(ptrMsg + count) != ' ' ) { *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) != ' ' ) { *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参数,因此可以将其删除. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |