none
c++问题 RRS feed

  • 问题

  • int _tmain(int argc, _TCHAR* argv[])
    {
     string str;
     while(cin >> str)
     {
      cout << str << endl;
     }
     return 0;
    }

     

    在vs2008下,以上代码为什么第一个ctrl+Z没有被当做文件结束符处理?

    例如

     


    stay hungry,stay foolish!
    2011年10月26日 12:56

答案

  • ctrl+Z 是 ASCII 26,这是一个非可打印字符,好像是右箭头。

    而 文本模式的文件以这个字符表示文件尾,所以在文本模式的文件里如果有这个字符,那么 fgetc 之类的函数可能不能完全读取文件。

     

    而stdin提交输入是以回车为结束的。

    而 istream 的 entry 和 fget 不一致 istream 有缓冲机制,所以在行的非起始Ctrl-Z的时候, ReadFile将整行全部读取进入缓冲区。而istream >> string 的时候,直接读取缓冲区的字符,检测不到 EOF。

    而当 Ctrl-z 是行首的时候,ReadFile立刻读取到 EOF,返回读取字符数为0,此时fget 返回 EOF,istream 认为是结束了。那么此时 istream >> string 返回 false.

     

    很久以前的知识了,不知道正确与否,仅供参考。

    现在几乎用不到这个精确了,控制台的这个操作只有 DOS 年代才被很多人精确使用。

     

    • 已建议为答案 Helen Zhao 2011年11月3日 7:30
    • 已标记为答案 Helen Zhao 2011年11月8日 5:02
    2011年10月27日 3:09
  • CTR+Z是Windows的输入文件结束符。
     
    Windows系统中一般采用阻塞式检查Ctrl+Z。
    这种阻塞式的方式有一个特点:只有按下回车之后才有可能检测在此之前是否有Ctrl+Z按下。还有一个特点就是:如果输入缓冲区中有可读的数据,则不会检测Ctrl+Z(因为有要读的数据,还不能认为到了流的末尾)。还有一点需要知道,Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的 不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区。
     
    从键盘上输入hello world然后Ctrl+Z,按回车以后,Windows是这样处理的:由于回车的作用,前面的hello world被送到输入缓冲区(^Z不产生字符,所以不被存储到缓冲区)。所以流不会结束。
     
    因此,输入流结束的条件就是:^Z之前不能有任何字符输入(回车除外),否则 ^Z 起不到结束流的作用。

    Helen Zhao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已建议为答案 Helen Zhao 2011年11月3日 7:30
    • 已标记为答案 Helen Zhao 2011年11月8日 5:02
    2011年11月2日 9:42

全部回复

  • 回车 - Ctrl+'Z' - 回车结束


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
    2011年10月27日 0:33
    版主
  • 恩,我知道这样可以结束.

    但为什么如果ctrl+‘Z’如果直接跟在后面不会被当做文件结束符处理?


    stay hungry,stay foolish!
    2011年10月27日 2:23
  • ctrl+Z 是 ASCII 26,这是一个非可打印字符,好像是右箭头。

    而 文本模式的文件以这个字符表示文件尾,所以在文本模式的文件里如果有这个字符,那么 fgetc 之类的函数可能不能完全读取文件。

     

    而stdin提交输入是以回车为结束的。

    而 istream 的 entry 和 fget 不一致 istream 有缓冲机制,所以在行的非起始Ctrl-Z的时候, ReadFile将整行全部读取进入缓冲区。而istream >> string 的时候,直接读取缓冲区的字符,检测不到 EOF。

    而当 Ctrl-z 是行首的时候,ReadFile立刻读取到 EOF,返回读取字符数为0,此时fget 返回 EOF,istream 认为是结束了。那么此时 istream >> string 返回 false.

     

    很久以前的知识了,不知道正确与否,仅供参考。

    现在几乎用不到这个精确了,控制台的这个操作只有 DOS 年代才被很多人精确使用。

     

    • 已建议为答案 Helen Zhao 2011年11月3日 7:30
    • 已标记为答案 Helen Zhao 2011年11月8日 5:02
    2011年10月27日 3:09
  • CTR+Z是Windows的输入文件结束符。
     
    Windows系统中一般采用阻塞式检查Ctrl+Z。
    这种阻塞式的方式有一个特点:只有按下回车之后才有可能检测在此之前是否有Ctrl+Z按下。还有一个特点就是:如果输入缓冲区中有可读的数据,则不会检测Ctrl+Z(因为有要读的数据,还不能认为到了流的末尾)。还有一点需要知道,Ctrl+Z产生的不是一个普通的ASCII码值,也就是说它产生的 不是一个字符,所以不会跟其它从键盘上输入的字符一样能够存放在输入缓冲区。
     
    从键盘上输入hello world然后Ctrl+Z,按回车以后,Windows是这样处理的:由于回车的作用,前面的hello world被送到输入缓冲区(^Z不产生字符,所以不被存储到缓冲区)。所以流不会结束。
     
    因此,输入流结束的条件就是:^Z之前不能有任何字符输入(回车除外),否则 ^Z 起不到结束流的作用。

    Helen Zhao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已建议为答案 Helen Zhao 2011年11月3日 7:30
    • 已标记为答案 Helen Zhao 2011年11月8日 5:02
    2011年11月2日 9:42