c语言中get()函数的原理及返回值

转载自CSDN博客:http://blog.csdn.net/shenglanya/article/details/52213500

首先要记住的一句话就是Never use gets().
这是因为gets()函数不检查目标数组是否能够容纳输入,而若想把一个字符串读到程序中,最先要做的事情就是预留存储字符串的空间。所以这很容易导致分配的空间不够大而数组越界,然而gets()函数并不检查这个方面,所以导致的结果就是程序很容易出现漏洞,著名的“蠕虫”病毒的原理就是用很长的数据覆盖原有数据导致崩溃。所以对于重要的编程,永远不要使用gets()!

1, gets()的参数是一个地址,因为要把从键盘输入的值确定的放到某一块内存中,所以需要指定它的地址,而通常使用gets(数组名)这种方式来把输入的字符串传入给定的数组中。注意:这个数组的大小一定要事先定义好!若不将数组的大小定义好,就有可能在输入的时候不知道把字符串输入到哪块内存中去了,就有可能会导致对该内存中原代码的覆盖。

2,    gets()的第一个用法:直接用gets(array‘s name);这种方式时,由于不知道什么时候才会到字符串结尾,所以每当键入‘\n‘, gets()函数都会自动读取换行符前面的所有内容并且在末尾加上‘\0‘,并且直接把这个字符串返回给调用它的程序,然后gets()再进行读取并且会把读取到的‘\n‘丢弃,这样下一次读取就会在新的一行开始。
例1:

[cpp] view plain copy

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX 81
  4. int main(void)
  5. {
  6. char name[MAX];
  7. printf("Hi, what‘s your name?\n");
  8. gets(name);
  9. printf("Nice name, %s\n", name);
  10. return 0;
  11. }
  12. /*
  13. Hi, what‘s your name?
  14. Herry potter
  15. Nice name, Herry potter
  16. */

3,  gets()的原型: char * gets(char * s)
                               {
                                          ...
                                       return s;
                               }
    所以由此可以看出gets()返回的是一个指向char类型数据的指针,而且这个指针与传递给他的是同一个指针。因此有如下程序:
例2:

[cpp] view plain copy

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX 81
  4. int main(void)
  5. {
  6. char name[MAX];
  7. char * ptr;
  8. printf("Hi,what‘s your name?\n");
  9. ptr = gets(name); // 这里的ptr是char类型的指针,此时ptr指向的是name的首地址。
  10. printf("%s? Ah? %s!", name, ptr); // 此时输出name和ptr指向的值,可以发现,他们的输出结果都一样。
  11. return 0;
  12. }
  13. /*
  14. Hi,what‘s your name?
  15. Herry
  16. Herry? Ah? Herry!
  17. */

4, 实际上gets()有两种可能的返回值类型:

1)当程序正常输入字符串时:返回读入字符串的地址,也就是字符串存放的数组的首地址;

2)当程序出现错误或者遇到文件结尾时:返回空指针NULL,注意不要弄混空指针和空字符(‘\0‘);
                                          所以可以很方便的用如下形式检测错误:
                                                                          while(gets(name) != NULL)

注意:现在基本上不使用gets(),可以说它是一个已经被废弃的函数,现在可以用scanf(), getchar(), fgets()来代替它。

时间: 2024-10-21 15:19:14

c语言中get()函数的原理及返回值的相关文章

C语言中system()函数的用法总结(转)

system()函数功能强大,很多人用却对它的原理知之甚少先看linux版system函数的源码: 1 #include <sys/types.h> 2 #include <sys/wait.h> 3 #include <errno.h> 4 #include <unistd.h> 5 6 int system(const char * cmdstring) 7 { 8 pid_t pid; 9 int status; 10 11 12 if(cmdstri

C语言中qsort函数用法

C语言中qsort函数用法-示例分析  本文实例汇总介绍了C语言中qsort函数用法,包括针对各种数据类型参数的排序,非常具有实用价值非常具有实用价值. 分享给大家供大家参考.C语言中的qsort函数包含在<stdlib.h>的头文件里,本文中排序都是采用的从小到大排序. 一.对int类型数组排序 int num[100]; int cmp ( const void *a , const void *b ) { return *(int *)a - *(int *)b; } qsort(num

(转)C语言中Exit函数的使用

C语言中Exit函数的使用 exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用.在多个进程时.如果有时要检测上进程是否正常退出的.就要用到上个进程的返回值.. exit(1)表示进程正常退出. 返回 1;exit(0)表示进程非正常退出. 返回 0.进程环境与进程控制(1): 进程的开始与终止 1. 进程的开始:C程序是从main函数开始执行, 原

R语言中apply函数

前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是为什么呢?原因在于R的循环操作for和while,都是基于R语言本身来实现的,而向量操作是基于底层的C语言函数实现的,从性能上来看,就会有比较明显的差距了.那么如何使用C的函数来实现向量计算呢,就是要用到apply的家族函数,包括apply, sapply, tapply, mapply, lapply, rapply, vapply, eapply等. 目录

C语言中access函数

int access(const char *filename, int amode); amode参数为0时表示检查文件的存在性,如果文件存在,返回0,不存在,返回-1. 这个函数还可以检查其它文件属性: 06     检查读写权限 04     检查读权限 02     检查写权限 01     检查执行权限 00     检查文件的存在性而这个就算这个文件没有读权限,也可以判断这个文件存在于否存在返回0,不存在返回-1 windows下_mkdir函数 #include<direct.h>

C语言中malloc函数的理解

在C语言中malloc函数主要是用在堆内存的申请上,使用malloc函数时,函数会返回一个void *类型的值,这个值就是你申请的堆内存的首地址:为什么返回的地址是一个void *类型的地址呢?首先我们要先弄明白,到底void是一个什么类型呢?很多C语言的初学者认为,void类型就是空类型,就是没有类型,但是实际上这种认知是扯淡的.因为空白的意思是可以容纳百物(讲C语言突然讲出了道家的思想,自己这么流弊的吗?哈哈哈哈哈嗝),既然可以容纳百物,也就是void型其实就是万能型,它可以指代任意类型.其

C语言中exit函数的使用

exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用.在多个进程时.如果有时要检测上进程是否正常退出的.就要用到上个进程的返回值.. exit(1)表示进程正常退出. 返回 1; exit(0)表示进程非正常退出. 返回 0. 进程环境与进程控制(1): 进程的开始与终止 1. 进程的开始: C程序是从main函数开始执行, 原型如下: int m

javascript学习笔记(二):定义函数、调用函数、参数、返回值、局部和全局变量

定义函数.调用函数.参数.返回值 关键字function定义函数,格式如下: function 函数名(){ 函数体 } 调用函数.参数.返回值的规则和c语言规则类似. 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta chaset="UTF-8"> 5 <title></title> 6 </head> 7 <body

C++笔记(3):函数的参数和返回值

刚学C++那会,做课程设计的时候总是会去网上很找别人写好的程序来参考,那时候看到函数参数列表里各种复杂的类型和奇怪的写法就头大,后来总算是慢慢搞清楚了,在此对函数各种类型的形参以及函数的返回值进行一下总结. 1.普通形参 传递普通形参也就是值传递,传递的是实际参数的一个副本,当函数被调用时,形参复制实参,也就是说此时形参和实参的值是一样的,但形参在内存中拥有自己的地址.当函数结束时形参的生命周期终止,函数内部的操作不会影响到实参的值.经典的值交换函数代码如下: void swap1(int a,