事例1(转)
 在程序中多次用的strcat函数,但是有时候编译通过,但是执行时却出现了错误。为了进一步了解strcat函数的使用,我首先写了这样的一个测试程序:
main()
{
       char *Temp=(char *)malloc(sizeof(char)*200);
       Temp="strcat";
       char *Append=" a test program!";
       strcat(Temp,Append);
       printf("%s\r\n",Temp);
       return 0;
}
      这个程序,从感觉上没有错误,而且编译也不会出现错误,但是就是运行时却出现了错误,错误的地方就是在strcat这个函数处。刚开始百思不得其解,后来恍然大悟,所以就把我如何理解和处理的过程写在这里,以备以后查阅。
1、分析原因 
      程序错误的原因:内存不允许写入。我想到strcat要有足够的空间来保存要连接的两个字符串,而我开辟的200个字节的空间怎么会容不下这几个两个字符串。原因肯定不是空间不够,我把Temp改成定义为变量,ok可以通过。难道是strcat的第一个参数不能为指针变量,我仔细看了函数的说明没有这样的要求,所以也不是这个问题。
      后来,我单步运行程序,发现了问题的症结所在。在定义了一个基类型为char类型的Temp指针变量并给他分配了200个字节的空间,但是执行到下一行就出现问题了Temp的值变了。这个原因我当时没有想到,后来仔细想想自己曾经总结过,是因为后面的字符串被当做了字符串常量,存储到了常量区,而Temp存储这个常量区首字符地址,所以根本就不是动态分配的空间。而后面strcat试图将一个字符串写入到一个常量区,所以出现了不允许写入的问题。
      原因找到了,下面就是如何解决这个问题了。
2、问题解决
     为了解决这个问题,我想出了两个解决方案:
 为了解决这个问题,我想出了两个解决方案:
     2.1、将strcat的第一个参数定义为数组,这样就避免了其在常量区的问题,问题得到了解决,哈哈,有点得意忘形了。有人问我习惯使用指针存储字符串怎么办?
    2.2、没有关系,也是有解决的办法的,使用指针,并给其分配足够的空间,下面就是赋值的问题,如果不采用像上面的赋值方式那样就可以了,但是如何把一个字符串写到一个已分配的空间。我想到了strcpy这个函数,他可以把你的字符串写入到你给他分配的空间里去。
     问题总算解决了,困扰了我几天的问题终于算搞明白了,是否一点问题都没有了,还有待于以后发现。
 
事例2:

在vc6中编程如下函数:

  1. #include "stdafx.h"
  2. #include
  3. #include
  4. using namespace std;
  5. int main(int argc, char* argv[])
  6. {
  7. char *p="abcde";
  8. int l=strlen(p);
  9. char *s="12345";
  10. strcpy(p,s);
  11. strcat(p,s);
  12. return 0;
  13. }

编译时可以通过,运行时却会出现access violation,这个错误的意思是说访问了一块已经失效的内存,究其原因,char *p="abcde",这一行在执行时,"abcde"(字符串常量)是位于文字常量区,这个区域的内容是不能修改的,而p这个指针变量是位于栈区,也就是说p指向了文字常量区的一个字符串。下面一行char *s的意义相同。

当在执行strcpy(p,s)时,它试图将p所指向的一块内存区域中的内容修改,而这是不可能的,所以会出现上面的那个错误,在执行strcat(p,s)时,它也是试图在修改文字常量区的内容,所以会错误。

当改成以下代码时就不会出现错误:

  1. #include "stdafx.h"
  2. #include
  3. #include
  4. using namespace std;
  5. int main(int argc, char* argv[])
  6. {
  7. char *p="abcde";
  8. int l=strlen(p);
  9. char *s="12345";
  10. //strcpy(p,s);
  11. //strcat(p,s);
  12. char a[]="abcde";
  13. char b[]="12345";
  14. char c[6];
  15. strcat(a,b);
  16. strcpy(c,b);
  17. return 0;
  18. }

此时就不会出错,因为char a[]="abcde"和char *p="abcde"它们的意义是完全不同的,前者的指针变量a是在栈区的,它所指向的"abcde"也是在栈区的,也就是说,a所指向的内存中的内容是可以被修改的。strcat(a,b)的意义也是类似的。

3,strcpy用法:

#include <string.h>
#include <malloc.h>
int main()
{
    const char *b ="abc";
    char *a = NULL; //这个指针要先分配空间
    a=(char *)malloc(10000);
    strcpy(a,b);
    printf("%s",a); //输出字符串的形式应该是%s
    free(a);//别忘了 释放内存
    return 0;
}

strcat strcpy 使用出现的问题汇总的更多相关文章

  1. strlen strcat strcpy strcmp 自己实现

    strlen strcat strcpy strcmp 自己实现 strlen include <stdio.h> #include <string.h> #include & ...

  2. 自己实现字符串操作函数strlen(),strcat(),strcpy(),strcmp()

    1.strlen()函数是求解字符串的有效长度的 1)非递归实现 size_t my_strlen(const char *str) { assert(str != NULL);  //断言,保证指针 ...

  3. strlen sizeof strcat strcpy区别

      strlen(p): 能计算出p指向字符串的长度(以当前p的位置开始),不包含终止字符'\0': p可以声明为char* p或者char p[],这两种形式strlen均能正确计算. sizeof ...

  4. strcat strcpy 源代码,用指针去实现

    15. 指针实现 strcmp函数     •    int newStrcpy(char *p, char *q)     •    {     •        while(*p ==*q) { ...

  5. 字符串操作函数<string.h>相关函数strcpy,strcat,等源码。

    首先说一下源码到底在哪里找. 我们在文件中包含<cstring>时,如果点击右键打开文档, 会打开cstring,我们会发现路径为: D:\Program Files\visual stu ...

  6. 由strcat函数引发的C语言中数组和指针问题的思考

    问题一 首先,来看一下下面这段代码: #include <stdio.h> #include <string.h> int main() { char *str = " ...

  7. c++语言知识点汇总

    c++ primer version-5 的整理 section 1: 内置类型和自定义类型: main函数的返回值:指示状态.0:成功:1:系统定义. unix和win系统中,执行完程序可以使用ec ...

  8. SCNU 2015ACM新生赛初赛【1007. ZLM的扑克牌】解题报告

            题目链接详见SCNU 2015新生网络赛 1007. ZLM的扑克牌 .         其实我在想这题的时候,还想过要不要设置求最小的排列,并且对于回文数字的话,可以把扑克牌折起来( ...

  9. 慕课网:C++ & 数据结构

    课程链接:james_yuan的课程 这部分太枯燥了,如果教材难度稍大,根本就学不下去,所以就先看看通俗的视频吧. 课程目录 1.C++远征之起航篇 - C++亮点尽在其中 2.C++远征之离港篇 - ...

随机推荐

  1. Objective-c——UI进阶开发第一天(UIPickerView和UIDatePicker)

    一.知识点 1.介绍数据选择控件UIPickerView和日期选择控件UIDatePicker控件 * UIPickerView的案例 * 点餐系统 * 城市选择 * 国旗选择 * UIDatePic ...

  2. foreach属性-动态-mybatis中使用map类型参数,其中key为列名,value为列值

    http://zhangxiong0301.iteye.com/blog/2242723 最近有个需求,就是使用mybatis时,向mysql中插入数据,其参数为map类型,map里面的key为列名, ...

  3. 分布式id 实现方式

    1. uuid 2. twitter的Snowflake 3. MongoDB ObjectID 4. Ticket Server 5. Instagram采用的方式(UUID方式)

  4. Node.js热部署方式

    1. supervisor: 2. hotnode: 3. node-dev: 4. nodemon:

  5. php返回json,xml,JSONP等格式的数据

    php返回json,xml,JSONP等格式的数据 返回json数据: header('Content-Type:application/json; charset=utf-8'); $arr = a ...

  6. nodejs初探(二)第一个nodejs程序“hello world”

    直接用文本编辑器编写helloworld.js,保存在桌面 var http = require("http"); http.createServer(function(reque ...

  7. OSX 10.11 cocoapods安装命令: sudo gem install -n /usr/local/bin cocoapods

    10.11 cocoapods安装命令: sudo gem install -n /usr/local/bin cocoapods

  8. 怎么取消 Windows Server 2012 r2 RDP 限制每个用户只能进行一个会话(转)

    在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...

  9. 黑马程序员_JAVA之银行业务调度系统

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 1.模拟实现银行业务调度系统逻辑,具体需求如下: 银行内有6个业务窗口,1 - 4号窗口为普通窗 ...

  10. Codeforces Round #226 (Div. 2) B

    B. Bear and Strings time limit per test 1 second memory limit per test 256 megabytes input standard ...