XCode中的EOF字符(ctrl + d)

时间:2010-02-21 06:17:14

标签: c eof

我正在做一个新任务,我的教授使用这段代码来测试我们的程序:

int main()
{
   const int SZ1 = 10;
   const int SZ2 = 7;
   const int SZ3 = 5;
   float array1[SZ1];
   float array2[SZ2];
   float array3[SZ3];

   DisplayValues(SortValues(GetValues(array1, SZ1), SZ1), SZ1);
   DisplayValues(SortValues(GetValues(array2, SZ2), SZ2), SZ2);
   DisplayValues(SortValues(GetValues(array3, SZ3), SZ3), SZ3);

   return EXIT_SUCCESS;
}

float *DisplayValues(float *p, size_t n)
{
   float previous = *p, *ptr, *end = p + n;

   setiosflags(ios_base::fixed);
   for (ptr = p; ptr < end; ++ptr)  // get each element
   {
      cout << *ptr << '\n';
      if (ptr != p)                 // if not first element...
      {
         if (previous < *ptr)       // ...check sort order
         {
            cerr << "Error - Array sorted incorrectly\n";
            return NULL;
         }
      }
      previous = *ptr;              // save this element
   }
   resetiosflags(ios_base::fixed);

   return p;
}
#endif

我用

float *GetValues(float *p, size_t n) 
{   
    float input;
    float *start = p;

    cout << "Enter " << n << " float values separated by whitespace: \n";

    while (scanf("%f", &input) == 1) {
        *p++ = input;
    }
    return start;
}

按照指示从终端窗口获取输入,并使用ctrl + d输入EOF字符,以便第一次调用DisplayValues(SortValues(GetValues(array1,SZ1),SZ1),SZ1)。但是,当DisplayValues(SortValues(array2,SZ2),SZ2),SZ2)时,程序的其余部分刚刚完成而不让我再次输入值;叫做。这有什么理由或解决方法吗?感谢。

2 个答案:

答案 0 :(得分:4)

CTRL D 字符(十六进制04)本身不是文件结尾字符。按下该键序列将向终端驱动器发出信号,告知这是输入流的结束,并且来自该流的任何进一步读取将被视为“文件”完成。实际上,您可以使用UNIX下的stty命令更改用于此的字符。

按下该序列时会发生什么,不会给程序提供进一步的输入。您需要找到一个更智能的序列来分隔您的数据(例如,换行符(0x10))。

但是这需要你输入字符串而不是浮点数(你可以使用fgets来获取字符串,sscanf在检查之后提取一个浮点空行。)

另一种可能性是使用-1作为特殊的标记值(假设-1不是有效输入)但要注意浮点比较,它们有时不是你所期望的。

我的建议是走fgets/sscanf路线,但由于您需要获得n个浮点数,因此您的GetValues应该是这样的:

float *GetValues (float *p, size_t n) {   
    float input;
    float *start = p;
    cout << "Enter " << n << " float values separated by whitespace: \n";
    while (scanf("%f", &input) == 1) {
        *p++ = input;
        if (--n >= 0)
            break;
    }
    return start;
}

一旦达到限制就会停止获取值。请记住,这并不完美。我在那里留下了至少一个问题,因为它是家庭作业(根据您的输入数据,您可能永远不会打它)。

我还应该提到混合C ++和C I / O语义(coutscanf)有点不寻常 - 你真的应该选择其中一个。如果这是一个C ++赋值,你会发现C ++有更丰富的I / O方式。如果它是C,那么cout在代码中没有位置,您应该使用printf。我不是说它不会工作,只是它是一种不寻常的混合。

答案 1 :(得分:0)

问题在于使用EOF作为分隔符。 scanf将在EOF中读取,然后才能获得它想要的下一个浮点数。 scanf将返回EOF以告诉您它找到了什么,但EOF不会离开缓冲区,因此下次您致电scanf时,它仍然会读取EOF并立即返回。请参阅:scanf

在你的GetValues函数中,由于你有数组的大小,你应该只读入数字,直到你有那么多的浮点数,而不是等待EOF。这样就可以防止溢出以及不正确地使用EOF。