从字符串中去除空间-带指针的原位C样式 [英] Space removal from a String - In Place C style with Pointers

查看:82
本文介绍了从字符串中去除空间-带指针的原位C样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,这是一个非常简单的问题,我知道解决方案是一个简单的功能,如下所示:

So, its a pretty simple problem and I know the solution which is a simple function like the one below:

  void removeSpaces(char* s) {
    char* source = s;
    char* dest = s;

    while(*source) {
        if(*source == ' ') {
            source++;
        } else {
            *dest++ = *source++;
        }
    }

    *dest = 0;
}

我正在使用Visual C ++ 2008 Express版

I am working in Visual C++ 2008 Express edition

当我用以下命令调用它时,它可以正常工作而不会出现任何问题,即它删除了所有空格:

When I call it with the following it works fine without any issues i.e it removes all the spaces:

int main() {
    char input[50] = "I       like            2% milk";
    removeSpaces(input);
    cout<<input;

    getchar();
    return 0;
}

但是,问题是当我通过将字符串声明更改为此来调用它时:

But, the problem is when I call it by changing the string declaration to this:

char * input = "I       like            2% milk";

我遇到异常(某种访问冲突)

I get a exception (some kind of access violation)

removeSpace函数的这一行代码上显示了异常

The exception is showing on this line of code of the removeSpace function

*dest++ = *source++;

有人能详细说明为什么会发生这种情况吗?

Can anyone elaborate as to why is this happening?

推荐答案

执行时

char* something = "a string literal";

编译器将"a string literal"放入可执行映像本身,并仅将指向该存储器的指针分配给something.不允许您修改此内存,并且字符串所驻留的内存很多次都被标记为只读,因此任何尝试写入该内存的操作都会导致访问冲突,就像您遇到的那样.

The compiler puts "a string literal" into the executable image itself and just assigns a pointer to this memory to something. You are not allowed to modify this memory, and many times the memory that the string resides in is marked read-only, so any attempts to write to it result in an access violation like the one you experienced.

完成时

char something[] = "a string literal";

您实际上是在名为something的堆栈上创建一个数组,并使用"a string literal"初始化 .这等效于执行char something[] = {'a', ' ', 's', 't', 'r', ..., 'a', 'l', 0};.由于此内存在堆栈中,因此您可以自由地对其进行修改.

you are really creating an array on the stack named something and initialising it with "a string literal". This is equivalent of doing char something[] = {'a', ' ', 's', 't', 'r', ..., 'a', 'l', 0};. Since this memory is on the stack, you can modify it freely.

char* something = "a string literal"看起来像

    stack                              executable

-------------                     ---------------------
|~~~~~~~~~~~|                     | ~~~~~~~~~~~~~~~~~ |
| something | ----------------->  | a string literal0 |
-------------                     | ~~~~~~~~~~~~~~~~~ |
                                  ---------------------

char something[] = "a string literal"看起来像

stack

-----
|~~~|
| a |  <- something is an alias for this location
|   |
| s |
| t |
| r |
| i |
| n |
| g |
|   |
| l |
| i |
| t |
| e |
| r |
| a |
| l |
| 0 |
-----

~~~的意思是其他内存等".

Where ~~~ means "other memory etc".

请注意

char* x = "string literal";

实际上是无效的,不应编译,因为您不能将char const[x]转换为char*.应该是const char* x,而不是char* x,但是某些旧的和不合格的编译器错误地允许了这种行为.

Is actually invalid and should not compile because you cannot convert a char const[x] to a char*. It should be const char* x, not char* x, but some old and non-conformant compilers wrongly allow this behaviour.

这篇关于从字符串中去除空间-带指针的原位C样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆