关于字符串修改的问题

新手上路,请多包涵

题目描述

修改字符串中某个字符为'0'

题目来源及自己的思路

在阅读某项目时发现此问题, 然后写了相关代码之后,发现还是有问题,但我又并不理解。

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

//code 1

#include<stdio.h>
#include<stdlib.h>


char *
duo_split_at(char *s, char delimiter, unsigned int position)
{
    unsigned int count = 0;
    char *iter = NULL;
    char *result = s;

    for (iter = s; *iter; iter++) {
        if (*iter == delimiter) {
            if (count < position) {
                result = iter + 1;
                count++;
            }
            *iter = '\0';
        }
        if(*iter !='\0'){
            printf("%c\n",*iter);
        }
    }

    if (count < position) {
        return NULL;
    }

    return result;
}

int main(){
    const char delimiter = '/';
    const unsigned int delimited_position = 5;
    char *user;
   // char *pw_geco ;
    char *pw_geco = "code1/code2/code3//textField/usergecosparsed";
    user = duo_split_at(pw_geco, delimiter, delimited_position);

    printf("%s\n%s\n",user,pw_geco);

    return 0;
}

请输入代码


//code 2

#include<stdio.h>
#include<stdlib.h>


char *
duo_split_at(char *s, char delimiter, unsigned int position)
{
    unsigned int count = 0;
    char *iter = NULL;
    char *result = s;

    for (iter = s; *iter; iter++) {
        if (*iter == delimiter) {
            if (count < position) {
                result = iter + 1;
                count++;
            }
            *iter = '\0';
        }
        if(*iter !='\0'){
            printf("%c\n",*iter);
        }
    }

    if (count < position) {
        return NULL;
    }

    return result;
}

int main(){
    const char delimiter = '/';
    const unsigned int delimited_position = 5;
    char *user;
   // char *pw_geco ;
    char pw_geco[] = "code1/code2/code3//textField/usergecosparsed";
    user = duo_split_at(pw_geco, delimiter, delimited_position);

    printf("%s\n%s\n",user,pw_geco);

    return 0;
}
//code 3

#include<stdio.h>
#include<stdlib.h>


char *
duo_split_at(char *s, char delimiter, unsigned int position)
{
    unsigned int count = 0;
    char *iter = NULL;
    char *result = s;

    for (iter = s; *iter; iter++)
    {
        if (*iter == delimiter)
        {
            if (count < position)
            {
                result = iter + 1;
                count++;
            }
            *iter = '\0';
        }
        if(*iter !='\0')
        {
            printf("%c\n",*iter);
        }
    }

    if (count < position)
    {
        return NULL;
    }

    return result;
}

int
main ()
{
    char* user = "daijwei";
    struct passwd *pw;
    if((pw = getpwnam(user)) == NULL)
    {
        printf("error");
        return -1;
    }
    const char delimiter = '/';
    const unsigned int delimited_position = 5;
    user = duo_split_at (pw->pw_gecos, delimiter, delimited_position);

    printf ("%s\n%s\n", user, pw->pw_gecos);

    return 0;
}

你期待的结果是什么?实际看到的错误信息又是什么?

假定用户gecos格式为"code1/code2/code3//textField/usergecosparsed"
这三段代码的效果都是为了实现同一个功能, 去除linux 用户gecos 中的usergecosparsed , code1 中会报错,无法执行, 查询过后说是因为char pw_geco 不能被修改, 因为是用char 定义的字符串。
修改为code2之后可以顺利执行。
但是为什么code3也可以顺利执行呢? struct passwd 中定义的 pw_geocs 也是用char* 定义的啊,所以我十分懵逼, 求解为什么会这样。

阅读 1.9k
2 个回答

开始我也感觉是能修改成功的,但是试了一下你的代码后,也发现了你说的问题。然后看了 getpwnam()的源码后,我想可以这样解释。
首先说一下你的第一次的代码为什么不能成功:
char *pw_geco = "code1/code2/code3//textField/usergecosparsed";
你这样定义的是使 pw_gecon 这个指针变量指向了 "code1/code2/code3//textField/usergecosparsed" 这个字符串常量,所以接下来你的代码想要改变这个常量的值,所以系统不会让你修改。所以如果你把代码改成这样:
char *pw_geco=NULL;
char pw_geco=(char)malloc(200); //为这个 pw_geco指针变量申请内存,存放字符串.
sprintf(pw_geco,"%s","code1/code2/code3//textField/usergecosparsed");
这样你再去改变通过 pw_geco 这个指针变量改变的就不是常量字符串。而是 pw_geco 指向的一个可变的字符串。

问题不在于“用char定义的字符串不能修改”,而在于将字符串常量赋值给了char*。
ISO C++禁止字符串字面常量转型为char*。对于字面常量"code1/code2/code3//textField/usergecosparsed",你可以写

const char* str = "code1/code2/code3//textField/usergecosparsed";

不能将const去掉。
从类型上说,const T不能转为T;从实现上讲,字面常量放置在程序的常量段,修改可能会触发保护机制。
修改char*变量指向的内存本身没有任何问题,所以code3可以顺利执行。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进