精华内容
下载资源
问答
  • 各位,今天看了一个典型的代码...=EOF){...}这段代码的本意是用getchar函数读取缓冲区字符直到结束,但是在编译运行时,发现上面几行代码一直报错!逻辑上没问题啊,那这究竟错在哪里?读者可以自己思考一下再往下...

    各位,今天看了一个典型的代码错误,比较有代表性,而且这也是大多数人在C编程中经常忽略的问题之一,拿出来与大家分享,希望大家以后避免类似的错误,代码如下:

    char c;while((c=getchar())!=EOF){...}

    这段代码的本意是用getchar函数读取缓冲区字符直到结束,但是在编译运行时,发现上面几行代码一直报错!逻辑上没问题啊,那这究竟错在哪里?读者可以自己思考一下再往下看。

    其实产生报错的原因有两点,一个是对getchar函数理解不到位,另一个是EOF的问题。

    我们首先来说说getchar函数的问题,标准库中给出了该函数的使用说明:在它读取一个字符后,会将其转换为int类型返回,所以首先char c要改为int c,关于getchar的问题还没讲完,后面还要说。

    我们接着来看看EOF的问题,初学者对它的理解经常会有偏差:首先它是一个宏,定义于头文件,为-1;其次它并不是很多人理解的文件结束符,实际上它是一个标志位,区别于其他所有字符的存在,表示一种没有其他字符的信号。

    讲到这里,我们再回到getchar函数,由上面可以看出它的返回值必须是一个能包含所有字符的数据类型,方便它表示任意字符和EOF等标志位。

    因此,上面代码的错误就很明显了,可能有两种情况:

    1.如果编译器中的char是有符号的且EOF被定义为-1,而恰好有字符等于0xff,那么getchar就会提前结束。当然,如果输入全部是7位以下的字符,那很长时间不会有错误。

    2.如果编译器中的char是无符号的,则实际的EOF值会被截断,不再会识别为EOF,将会陷入无限循环。

    这里肯定会有人问我们键入-1来模拟EOF跳出循环不行吗?实际上是不行的,-1是有-和1两个字符组成的,而getchar一次只能读取一个字符,所以上述代码EOF与从键盘输入的字符无关,那这岂不是只能死循环了?当然不是,我们可以通过按键组合ctrl+d或者ctrl+z来指示结束,当然,这里的按键组合输入只是我们的一种约定,不应该显示检查按键组合的值。

    讲到这里大家应该明白了吧,希望对大家有所帮助,感谢耐心阅读!

    c96392aad3a1789dae649aebc61f3eb4.png

    展开全文
  • 认识io.EOFio.EOF是io包中的变量, 表示文件结束的错误:```gopackage iovar EOF = errors.New("EOF")```也通过以下命令查看详细文档:```$ go doc io.EOFvar EOF = errors.New("EOF")EOF is the error returned by ...

    3642976d9a2ab5bc7fa22cf2f412f194.png

    ## 1. 认识io.EOF

    io.EOF是io包中的变量, 表示文件结束的错误:

    ```go

    package io

    var EOF = errors.New("EOF")

    ```

    也通过以下命令查看详细文档:

    ```

    $ go doc io.EOF

    var EOF = errors.New("EOF")

    EOF is the error returned by Read when no more input is available. Functions

    should return EOF only to signal a graceful end of input. If the EOF occurs

    unexpectedly in a structured data stream, the appropriate error is either

    ErrUnexpectedEOF or some other error giving more detail.

    $

    ```

    io.EOF大约可以算是Go语言中最重要的错误变量了,  它用于表示输入流的结尾. 因为每个文件都有一个结尾, 所以io.EOF很多时候并不能算是一个错误, 它更重要的是一个表示输入流结束了.

    ## 2. io.EOF设计的缺陷

    可惜标准库中的io.EOF的设计是有问题的. 首先EOF是End-Of-File的缩写, 根据Go语言的习惯大写字母缩写一般表示常量. 可惜io.EOF被错误地定义成了变量, 这导致了API权限的扩散. 而最小化API权限是任何一个模块或函数设计的最高要求. 通过最小化的权限, 可以尽早发现代码中不必要的错误.

    比如Go语言一个重要的安全设计就是禁止隐式的类型转换. 因此这个设计我们就可以很容易发现程序的BUG. 此外Go语言禁止定义没有被使用到的局部变量(函数参数除外, 因此函数参数是函数接口的一个部分)和禁止导入没有用到的包都是最小化权限的最佳实践. 这些最小API权限的设计不仅仅改进了程序的质量, 也提高了编译工具的性能和输出的目标文件.

    因为EOF被定义成一个变量, 这导致了该变量可能会被恶意改变. 下面的代码就是一种优雅的埋坑方式:

    ```go

    func init() {

        io.EOF = nil

    }

    ```

    这虽然是一个段子, 但是却真实地暴漏了EOF接口的设计缺陷: 它存在严重的安全隐患. 变量的类型似乎也在暗示用户可以放心地修改变量的值. 因此说EOF是一个不安全也不优雅的设计.

    ## 3. io.EOF改为常量

    一个显然的改进思路是将io.EOF定义为常量. 但是因为EOF对应一个表示error接口类型, 而Go语言目前的常量语法并不支持定义常量类型的接口. 但是我们可以通过一些技巧绕过这个限制.

    Go语言的常量有bool/int/float/string/nil这几种主要类型. 常量不仅仅不包含接口等复杂类型, 甚至连常量的数组或结构体都不支持! 不过常量有一个重要的扩展规则: 以bool/int/float/string/nil为基础类型定义的新类型也支持常量.

    比如, 我们重新定义一个字符串类型, 它也可以支持常量的:

    ```go

    type MyString string

    const name MyString = "chai2010"

    ```

    这个例子中MyString是一个新定义的类型, 可以定义这种类型的常量, 因为它的底层的string类型是支持常量的.

    那么io.EOF的底层类型是什么呢? EOF是通过errors.New("EOF")定义的, 下面是这个函数的实现:

    ```go

    package errors

    // New returns an error that formats as the given text.

    func New(text string) error {

        return &errorString{text}

    }

    // errorString is a trivial implementation of error.

    type errorString struct {

        s string

    }

    func (e *errorString) Error() string {

        return e.s

    }

    ```

    因此io.EOF底层的类型是errors.errorString结构体. 而结构体类型是不支持定义常量的. 不过errors.errorString结构体中只有一个字符串类型, io.EOF对应的错误字符串正是"EOF".

    我们可以为EOF重新实现一个以字符串为底层类型的新错误类型:

    ```go

    package io

    type errorString string

    func (e errorString) Error() string {

        return string(e)

    }

    ```

    这个新的io.errorString实现了两个特性: 首先是满足了error接口; 其次它是基于string类型重新定义, 因此支持定义常量. 因此我们可以基于errorString重新将io.EOF定义为常量:

    ```go

    const EOF = errorString("EOF")

    ```

    这样EOF就变成了编译时可以确定的常量类型, 常量的值依然是“EOF”字符串. 但是也带来了新的问题: EOF已经不再是一个接口类型, 它会破坏旧代码的兼容性吗?

    ## 4. EOF常量到error接口的隐式转换

    重新将EOF从error类型的变量改定义为errorString类型的常量并不会带来兼容问题!

    首先io.EOF虽然被定义为变量, 但是从语义角度看它其实是常量, 换言之我们只会读取这个值. 其次读取到io.EOF之后, 我们是将其作为error接口类型使用, 唯一的用处是和用户返回的错误进行相等性比较.

    比如有以下的代码:

    ```go

    func Foo(r io.Reader) {

        var p []byte

        if _, err := r.Read(p); err != io.EOF {

            // ...

        }

    }

    ```

    这里和io.EOF进行比较的err变量必然是error类型, 或者是满足error接口的其他类型. 如果err是接口类型, 那么将io.EOF换成errorString("EOF")常量也是可以工作的:

    ```go

    func Foo(r io.Reader) {

        var p []byte

        if _, err := r.Read(p); err != errorString("EOF") {

            // ...

        }

    }

    ```

    这是因为Go语言中一个普通类型的值在和接口类型的值进行比较运算时, 会被隐式转会为接口类型(开这个后门的原因时为了方便接口代码的编写). 或则说在进行比较的时刻, errorString("EOF")已经被替换成error(errorString("EOF")).

    普通类型到接口的隐式转会虽然方便, 但是也带来了很多坑. 比如以下的例子:

    ```go

    func Foo() error {

        var p *SomeError = nil

        return p

    }

    ```

    以上代码的nil其实是`*SomeError(nil)`. 而`if err != nil` 中的nil其实是error(nil).

    而定义为常量的io.EOF常量在和error接口类型的值比较时, io.EOF常量会被转化为对应的接口类型. 这样新的io.EOF错误常量就可以和以前的代码无缝兼容了.

    ## 5. 总结

    普通类型到接口类型的隐式转换、常量的默认类型和基础类型是Go语言中比较隐晦的特性, 很多人虽然在使用这些规则但是并没有意识到它们的细节. 本文从分析io.EOF设计缺陷为起点, 讨论了将常量用于接口值定义的一种思路.

    展开全文
  • EOF自定义终止符用法,我们在脚本中经常会发现使用EOF的情况。EOF可以结合cat命令对内容进行追加。比如:执行脚本的时候,需要往一个.......EOF //结束PS:EOF不是固定的,可以自定义其他,但需注意,结束符和起始符...

    9123d62d127d1dd42bbfd0291cf56273.png

    EOF自定义终止符用法,我们在脚本中经常会发现使用EOF的情况。EOF可以结合cat命令对内容进行追加。比如:执行脚本的时候,需要往一个文件里自动输入多行内容。如果是少数的几行内容,可以用echo命令追加,但如果是很多行,那么单纯用echo追加的方式就不太适合了。

    1.语法格式:

    <....EOF         //结束

    PS:EOF不是固定的,可以自定义其他,但需注意,结束符和起始符要保持一致

    2.重定向符号:

    < :输入重定向> :输出重定向>> :输出重定向,追加,不覆盖之前内容<< :标准输入来自命令行的一对分隔号的中间内容.

    3.案例:

    1)向eof.txt文件中写入内容(将EOF的输出作为cat命令的输入)

    # 输入内容到文件,如果文件有内容会覆盖[root@VM_0_10_centos shellScript]# cat << EOF > eof.txt> this is eof> eof> content> eof end> EOF[root@VM_0_10_centos shellScript]# cat eof.txtthis is eofeofcontenteof endeof[root@VM_0_10_centos shellScript]# cat > eof.txt << EOF> qwer> qaz> EOF

    输入内容到文件,不覆盖,以追加方式输入

    [root@VM_0_10_centos shellScript]# cat << EOF >> eof.txt> 12345> 56789> EOF[root@VM_0_10_centos shellScript]# cat eof.txtthis is eofeofcontenteof endeof1234556789[root@VM_0_10_centos shellScript]# cat >> eof.txt << EOF> wsx> edc> EOF[root@VM_0_10_centos shellScript]# cat eof.txtqwerqazwsxedc

    原文来自:https://www.cnblogs.com/HeiDi-BoKe/p/11692079.html

    本文地址:https://www.linuxprobe.com/linux-eof-diy.html编辑:张雄,审核员:逄增宝

    Linux命令大全:https://www.linuxcool.com/

    59e5a139d773b2ee59e86b225da1b0ac.png

    官方站点:www.linuxprobe.com

     Linux命令大全:www.linuxcool.com

    Linux系统下载站:www.linuxdown.com

    f2ffca318664ad92861f033598fcc7be.png

    刘遄老师QQ:5604922

    Linux技术交流群:193666693

    (新群,火热加群中……)

    书籍在线学习(电脑阅读效果佳)

    http://www.linuxprobe.com/chapter-00.html

        想要学习Linux系统的读者可以点击按钮来了解书籍《Linux就该这么学》,同时也非常适合专业的运维人员阅读,成为辅助您工作的高价值工具书!

    展开全文
  • 将命令中接收输入的途径由默认的键盘改为指定的文件。<命令序列传递到一个交互程序或者命令中。... EOF注意:EOF结束的标志(常用),可以修改为其他的。案例2:改进一下案例1将以上操作写到一个...

    将命令中接收输入的途径由默认的键盘改为指定的文件。

    <

    命令序列传递到一个交互程序或者命令中。

    单单看文字可能不太明白,我们看实例。

    案例1:

    使用<

    [root@kingdom input]# passwd odysee << EOF

    > 123456

    > 123456

    > EOF

    注意:

    EOF:结束的标志(常用),可以修改为其他的。

    208343515f32656914042ec5a6ac0f92.png

    案例2:

    改进一下案例1

    将以上操作写到一个脚本中,结束符可以用end

    #!bin/bash

    #修改传入用户的密码,使用<<

    #这里不做判断校验了

    #auth:odysee

    passwd $1 << end

    odysee

    odysee

    end

    3cf9a63144fd5be04d41029d739306b1.png

    执行

    bash update_user_passwd.sh odysee

    注意:

    记得传入一个用户

    5c7d59c367973c6f16fea78fd281e913.png

    案例3:

    案例2将密码直接写到脚本中,总归不太合适

    下面我们把写到一个文件中

    顺便引出我们的

    vi passwd.txt

    af5166809edb5f174d94bc68a55ddb47.png

    执行

    passwd odysee < passwd.txt

    03cd8f03256d450aeb246f41556d4e6a.png

    提示:

    只会读取文件的前两行。

    补充:

    关于<< 和

    lftp、自动创建mysql数据库等等。

    欢迎大家给予宝贵的意见或者建议。

    欢迎大家补充或者共享一些其他的方法。

    感谢支持。

    展开全文
  • set /p start_ip=请输入起始IP(A.B.C.D): set /p end_ip=请输入结束 IP 第四段数(1-255): echo --------------------------------信息确认------------------------------------- echo. ::IP切片分段 call:ip_cut ...
  • 对于许多没有做过PLC编程的人来说,不知道数字量输入模块的输出通道编址是怎么完成的,所以在现场调试过程中,遇到需要结合图纸、硬件模块和程序时,不能很快的找到对应的输入点。这篇文章就是要给大家解决这个问题...
  • Part 1....它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)... 解决办法:增加一个整型数组,对整型数组进行运算,结束后倒回字符数组。 II.解密过程 在代码注释中已说明。 Part 5.代码附上 #include
  • 衢州放心【公司内训】怎么选,主营项目:拓展培训、员工培训、激光镭战、彩弹野战、军训、员工活动策划与执行。 导致时间一长,参训人员就很快把内训的知识全部忘光,内训的效果就会大打折扣。内训后产生这样的情况...
  • cin.eof())//ctrl+z结束 { if (cin.bad())//系统级的错误,比如流缓冲区完整性du的缺失等,是无法恢复的 throw std::runtime_error("IOstream corrupted"); if (cin.fail())//输入的不是数字 { cerr ,try again" ; ...
  • expect中的关键字 #介绍 expect中的特特殊关键字用于匹配过程,代表某些特殊的含义或状态,一般只用于expect命令中而不能在expect命令单独使用 #1.eof关键字 eof(end-of-file文件结尾)关键字用于匹配结束符 #示例...
  • 相信大家在上次的学习中一定了解到EOF在C标准函数库中表示文件结束符,通常我们会在while循环中使用,例如while(scanf(“%d”,&a)!=EOF)该句语法的含义为:从键盘中读入若干组数据,例如以下示例: 其运行结果如下:...
  • 标准I/O:1.I/O(Input/Output)就是输入与输出的简称.2.标准I/O是ANSI C标准(C库)中定义的一系列用于I/O操作的函数.编程中,我们只要包含了相对应的头文件(.h)就可以调用我们要使用的标准输入输出函数.3.标准I/O一般...
  • = nil || err == io.EOF { fmt.Printf("received error: %v", err) break F } err = nil // 从头3位获取响应码 code := servRespMsg[0:3] fmt.Printf("Stage: %d, Code: %sn", stage, code) switch stage { case ...
  • 2019年8月25日14:20:32在牛客网的笔试上吃了输入格式的亏官方指南https://www.nowcoder.com/discuss/276 基本相当之坑。参考https://blog.csdn.net/dwqy11/article/details/892861061.理解机制刷题网站的后台给出的...
  • 英雄联盟手游在游戏中怎么加好友,有什么具体的办法去操作,此次想要和好友开黑,也是相处了很多的办法去加好友的,有什么方法去加别人为好友。下面就来介绍下怎么加好友。 添加好友我们需要打开好友列表,右上角...
  • C语言中,怎么EOF结束输入

    万次阅读 多人点赞 2018-07-15 22:06:25
    从数值上来看,就是整数-1在C语言的头文件中对其进行了宏定义:1libio.h: # define EOF (-1)当读文件操作时,遇到文件结束位置或读数据出错均会返回 EOF。 (C语言中所有的输入输出操作均是按读文件的思想来...
  • C++中怎么使用EOF结束输入

    万次阅读 2017-10-15 14:37:19
    #include using namespce std; void main() { int a; while(cin >>a) { ;//循环输入的代码块 ...运行程序之后循环输入,按下CTRL + Z 并且还得按下回车,当初就是没按回车一直不知道什么意思,输入还没有停止。
  • 7-12 排序(数组) (5分) ...唯一的难点就是怎么EOF结束了 while(cin>>x>>y){} while(scanf("%d %d",&x,&y)){} 但是对于这个题,如果输入一个数,以上两种方法肯定会出错 对
  • EOF是一个字符,End Of File的缩写,通常在文本的最后存在此字符表示资料结束。...Crtl+D 结束输入; Crtl+Z 强行终止; 比如scanf函数,在遇到错误或者读到EOF时会返回-1;可以测试下: #include<stdio.h>
  • 用JAVA做OJ时多组输入输入EOF结束

    千次阅读 2018-03-07 19:46:17
    但是对于初学java的,有一个难点,那就是题目要求以EOF结束,C、C++我们很熟悉,C语言的时候while(scanf(…)!=EOF),C++中while(cin&gt;&gt;?),java中怎么做呢? java中有个hasNext()函数,作用就是判断...
  • =EOF) /*这里*/ { r=decrypt(s1,s2); if(r) printf("Yes\n"); else printf("No\n"); } return 0; } [img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/26.gif][/...
  • mac cdt cin EOF输入

    千次阅读 2014-05-01 22:29:16
    使用Eclipse-cdt做开发的同学可能会遇到这样的问题,需要输入EOF作为结束标志结束输入,但是不知道怎么结束输入。 在网上搜了一堆解决方法,都是说windows下使用 Ctrl+Z 做EOF信号,unix和linux下用 Ctrl+D 做EOF...
  • 对于标准输入(也就是一般的键盘输入),需要人为的产生一个EOF,告诉系统输入结束了。Unix/Linux下一般使用Ctrl+d,Dos/Windows下是Ctrl+z或者\0结束。 注意: 还要加一个回车 …… 此时cin流已经处于无效状态了...
  • lim位字符数组s[]能容纳的最大元素个数,DOS窗口下输入:abc接下来输入文本结束符,情况1:在字符‘c’后面,直接输入文本结束符,即按Ctrl+z组合键,再按Enter情况2:在字符‘c’后面先按Enter,接着按Ctrl+z组合键...
  • 使用Eclipse-cdt做开发的同学可能会遇到这样的,需要输入EOF作为结束标志结束输入,但是不知道怎么结束输入。在网上搜了一堆解决方法,都是说windows下使用 Ctrl+Z 做EOF信号,unix和linux下用 Ctrl+D 做EOF信号。...
  • C语言怎么使用EOF

    千次阅读 2014-03-29 09:07:21
    在命令行中输入多行数据,最后以EOF结束时,如何输入EOF呢? 首先在最后一行结束输入ENTER键,再输入ctrl+z,再输入时ENTER键即可。

空空如也

空空如也

1 2 3 4
收藏数 62
精华内容 24
关键字:

eof怎么结束输入