user-0 提问: 编写一个程序，将字符数组s2中的全部字符复制到字符数组s1中，不用strcpy函数，编译结果不一致！

回复:
user: user-1
content: 引用 10 楼 mymtom 的回复:[quote=引用 5 楼 youjun610789338 的回复:]         单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体 判断参数？有必要吗？误人子弟啊！ 自己看看strcpy的实现吧！[/quote]  也不一定是必要的，如果自己传入的参数足够安全的话，可以不用判断入参，但是传个NULL给strcpy，运行就会出错，对入参进行断言判断体现的是严谨性，哪里来的误人子弟一说！

user: user-2
content: 引用 12 楼 u013409439 的回复:[quote=引用 11 楼 guicaisa 的回复:] 最后目标字符串里尾巴得加个'\0'吧。或者你这样初始化char str[80] = {0}; 断点调试就是在需要断点的地方按个F9，然后F5执行，F10单步执行，这时候自己观察监视器里每个变量的实时的数值啊，从而对是哪步出差错了可以很快的判别出来，F11进入函数，可以自己更直观的了解程序的执行流程。  哪里尾巴加个‘\0’? f11进入函数，进入函数都是看不懂的语句怎么破[/quote]  你不是用一个for循环然后s1[i] = s2[i]吗，循环结束后，目标字符串s1[i] = '\0';把尾巴填上。

user: user-0
content: 问题解决了，是scanf_s后面少个参数80，修改为scanf_s("%s",s2,80);就好了！多谢各位大神~

user: user-0
content: 引用 5 楼 youjun610789338 的回复:单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体  感谢倾心回复，感觉出来前辈的用心回复！ 我现在还处于看课后题自己不会编写，看了答案还需要好久才能看懂的或者直接硬着头皮比照着敲上去，然后在编译看效果的程度。 但是我用单步调试的时候其实好多也看不明白，会出现好多“烫烫烫”好多烫字让人很不解。 这个答案确实是我比照着敲得没有发现有错误，但是编译结果却不一致。 scanf_s是万不得已使用的，因为vs2013有保护程序，如果不这样先编译错误，说是会溢出。 前辈编写的程序有点看不懂，我刚看到函数那一章，貌似有指针

user: user-3
content: 恩，5楼说的很好

user: user-4
content: 恩，5楼说的很好，第四点，你用<=，所以还算ok吧

user: user-5
content: scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s 下面有一段话：4-6) Same as (1-3), except that %c, %s, and %[ conversion specifiers each expect two arguments (the usual pointer and a value of type rsize_t indicating the size of the receiving array,…… 意思是%c, %s, 和 %[，后面对应两个参数：一个指针和指示此数组大小的值 你的scanf_s后面少个参数80

user: user-0
content: 引用 13 楼 u013163178 的回复:#undef __stpcpy #undef stpcpy  #ifndef weak_alias # define __stpcpy stpcpy #endif  /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */ char * __stpcpy (dest, src)      char *dest;      const char *src; {   char *d = dest;   const char *s = src;  /*没有考虑内存重叠的情况*/   do     *d++ = *s;   while (*s++ != '\0');    return d - 1; }  表示看不懂  引用 13 楼 u013163178 的回复:#undef __stpcpy #undef stpcpy  #ifndef weak_alias # define __stpcpy stpcpy #endif  /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */ char * __stpcpy (dest, src)      char *dest;      const char *src; {   char *d = dest;   const char *s = src;  /*没有考虑内存重叠的情况*/   do     *d++ = *s;   while (*s++ != '\0');    return d - 1; }  话说看不懂

user: user-6
content: #undef __stpcpy #undef stpcpy  #ifndef weak_alias # define __stpcpy stpcpy #endif  /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST.  */ char * __stpcpy (dest, src)      char *dest;      const char *src; {   char *d = dest;   const char *s = src;  /*没有考虑内存重叠的情况*/   do     *d++ = *s;   while (*s++ != '\0');    return d - 1; }

user: user-0
content: 引用 11 楼 guicaisa 的回复:最后目标字符串里尾巴得加个'\0'吧。或者你这样初始化char str[80] = {0}; 断点调试就是在需要断点的地方按个F9，然后F5执行，F10单步执行，这时候自己观察监视器里每个变量的实时的数值啊，从而对是哪步出差错了可以很快的判别出来，F11进入函数，可以自己更直观的了解程序的执行流程。  哪里尾巴加个‘\0’? f11进入函数，进入函数都是看不懂的语句怎么破

user: user-2
content: 最后目标字符串里尾巴得加个'\0'吧。或者你这样初始化char str[80] = {0}; 断点调试就是在需要断点的地方按个F9，然后F5执行，F10单步执行，这时候自己观察监视器里每个变量的实时的数值啊，从而对是哪步出差错了可以很快的判别出来，F11进入函数，可以自己更直观的了解程序的执行流程。

user: user-7
content: 引用 5 楼 youjun610789338 的回复:单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体 判断参数？有必要吗？误人子弟啊！ 自己看看strcpy的实现吧！

user: user-8
content: VS有带文档，告诉你怎么用调试器。

user: user-1
content: 单步调试一般用一般就用F10，F11是step in，如果遇到库函数也会进入，比较多余         单步调试可以让你明白你的每一句代码都干了什么，是否达到了你要的效果，当程序最终执行结果和预想的不一致时，就可以利用单步调试排查具体哪一行代码出问题！          看了你的代码让我想起了N年前的我自己，菜鸟一个，我试着copy一下来验证，唉，copy完我就后悔了，还不如自己重写一遍。         先指出你代码中有问题的部分：         1、main函数最好是返回int类型         2、别用vs下特有的_s函数，看着眼生貌似很牛逼，如果是跨平台的话，移植的时候有的你蛋疼         3、数组最好初始化char s1[80] = {0};         4、你用strlen(s2)来做限制，那么字符串结束符'\0'就不会被拷贝到s1中，这样打印出来的s1结尾就是乱码         5、你的变量命名是不规范的，可以百度一下匈牙利命名法则。          再看看我写的代码吧：  #include <stdio.h> #include <assert.h> #include <string>  char* STRCPY(char* dest, const char* src){     assert((src != NULL)&&(dest != NULL));          char* pDest = dest;     do{         *dest = *src;         dest++,src++;     }while(*src != '\0');          return pDest; }     int main(int argc, char** argv){     char szBuf[80] = "youdalfaoduandljfaa";     char szBuf1[80] = {0};          STRCPY(szBuf1, szBuf);          printf("%s\n%s\n", szBuf, szBuf1);     return 0; }              这是一道比较经典的C笔试题，考点全在STRCPY函数里面，考点分为：         1、STRCPY必须返回char*         2、要有断言，对入参进行判断         3、copy循环体

user: user-0
content: 引用 楼主 u013409439 的回复: 如图所示编译结果不一致？  另外问各位大神那个“单步调试”具体怎么做，按f10吗？当看不懂程序的时候，单步调试能有什么好处，有什么帮助呢？  这个代码有错误，各位看看哪里错误了，编译的结果没有复制成功。

user: user-9
content: F9下断点，F5调试运行，这个程序F10单步，鼠标移上去看变量内容

user: user-10
content: 没有问题 F10       逐过程 F11       逐语句

user: user-11
content: F11 代码有bug，如果输入超过80个字符怎么办？