LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1788|回复: 16

如何用 C 编写字符串的替换?

[复制链接]
发表于 2005-5-10 19:37:59 | 显示全部楼层 |阅读模式
现在 C 不是很了解,最近学习中遇到了一个问题,就是替换一个字符串中的字符。比如

hello, world hello. 中

将全部的 hello 替换成 china 什么来着的,大家给一个思路也行

主要我的那本参考书里没有这到题目的解答,所以发到这里了请大家帮个忙,谢谢了。
发表于 2005-5-10 20:06:12 | 显示全部楼层
把本数据结构的书看看。字符串处理都有专门的算法。
回复 支持 反对

使用道具 举报

发表于 2005-5-10 20:15:16 | 显示全部楼层


  1. #include <errno.h>
  2. #include <sys/types.h>
  3. #include <string.h>

  4. int str_replace(char *str, size_t n,
  5.                 const char *old,
  6.                 const char *new)
  7. {
  8.     size_t old_len = strlen(old);
  9.     size_t new_len = strlen(new);
  10.     const char *end = str + n;

  11.     while (str = strstr(str, old))
  12.     {
  13.         size_t len = strlen(str);
  14.         if (str + len + new_len - old_len < end)
  15.         {
  16.             memmove(str + new_len, str + old_len, len + 1);
  17.             memcpy(str, new, new_len);
  18.             str += new_len;
  19.         }
  20.         else
  21.         {
  22.             errno = ENOSPC;
  23.             return -1;
  24.         }
  25.     }

  26.     return 0;
  27. }

复制代码


没有调试过的,你试试可不可以。
回复 支持 反对

使用道具 举报

发表于 2005-5-10 20:27:39 | 显示全部楼层
说明一下,str是一个字符串,n为从str起可用的空间。
显然,n>=strlen(str)+1。
例如:
char str[100]="hello, world hello";
str_replace(str, 100, "world", "china");
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-11 11:12:38 | 显示全部楼层
因为数据结构是这个学期开始学的,所以这方面的介绍还没有学过,有点不清楚

Tetris 兄的程序我实验过,可以使用 现在我正分析这段代码(不好意思,很多函数都没有碰到过)。

Tetris 兄能简单说一下它的算法吗?
回复 支持 反对

使用道具 举报

发表于 2005-5-12 13:22:18 | 显示全部楼层
To Tetris:
size_t 在 string.h 里已经定义了(由 C 标准规定),所以不必再包含 <sys/types.h>。此外,如果没有 ENOSPC 和 sys/types.h,你的程序就是 100% ANSI C 的了。对于这样一个函数,理当如此。
回复 支持 反对

使用道具 举报

发表于 2005-5-12 17:48:27 | 显示全部楼层
Post by herberteuler
To Tetris:
size_t 在 string.h 里已经定义了(由 C 标准规定),所以不必再包含 <sys/types.h>。此外,如果没有 ENOSPC 和 sys/types.h,你的程序就是 100% ANSI C 的了。对于这样一个函数,理当如此。


有道理。但好像<sys/types.h>是ANSI C里的吧?还有,我的习惯是,如果需要用到某一个数据类型,就应该直接include定义这个数据类型的头文件。
ENOSPC不是ANSI C的,但因为这个函数有可能返回错误,按我的习惯是返回错误就一定指明错误原因,所以就这么做了。其实不设置errno也可以,ANSI C就没有规定malloc分配内存失败要把errno置为ENOMEM。所以可以这个做:

  1.     if (...)
  2.     {
  3.         ...
  4.     }
  5.     else
  6.     {
  7. #ifdef ENOSPC
  8.         errno = ENOSPC
  9. #endif
  10.         return -1;
  11.     }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-5-12 18:56:48 | 显示全部楼层
Post by Tetris
有道理。但好像<sys/types.h>是ANSI C里的吧?还有,我的习惯是,如果需要用到某一个数据类型,就应该直接include定义这个数据类型的头文件。
ENOSPC不是ANSI C的,但因为这个函数有可能返回错误,按我的习惯是返回错误就一定指明错误原因,所以就这么做了。其实不设置errno也可以,ANSI C就没有规定malloc分配内存失败要把errno置为ENOMEM。所以可以这个做:

  1.     if (...)
  2.     {
  3.         ...
  4.     }
  5.     else
  6.     {
  7. #ifdef ENOSPC
  8.         errno = ENOSPC
  9. #endif
  10.         return -1;
  11.     }
复制代码

不,ANSI C 里的定义文件叫 stddef.h,并且包含 ANSI C 的头文件都是不需要 sys/types.h 这样的子目录的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-12 20:05:38 | 显示全部楼层
呵呵,一个问题可以拖出那么多有用的东西,再次感谢大家了
回复 支持 反对

使用道具 举报

发表于 2005-5-16 03:22:11 | 显示全部楼层
Post by herberteuler
不,ANSI C 里的定义文件叫 stddef.h,并且包含 ANSI C 的头文件都是不需要 sys/types.h 这样的子目录的。


不对,试了一下:
#include <ctypes.h>
int main(void)
{
    size_t a;
}

编译不过,呵呵。ctypes.h是ANSI C的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表