我如何解决字符串和inFile.open之间的数据冲突

时间:2010-09-30 23:14:10

标签: c++ string conflict

#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>

using namespace std;

**int main()
{
    double write();
    double read();
    string choice;

    while(1)
    {
      cout<<"Enter read to read a file and write to write a file.\n";
      cin>>choice;
      if (choice == "read")
        cout<< read();
      if (choice == "write")
        cout<< write();
    }
}

double read()
{    
    const int size = 60;
    ifstream inFile;
    char filename[size];
    cout<<"Enter the name of the file you want to read \n";
    cin.getline(filename, size);
    inFile.open(filename);**

    if(!inFile.is_open())
    {
      cout<<"could not open  "<<filename<<endl<<"program terminating";
      exit(EXIT_FAILURE);
    }

    double value;
    double sum = 0.0;
    int count = 0;
    inFile >> value;
    while(inFile.good()) 
    {
      cout<<value<<"\n";
      ++count;
      sum += value;
      inFile >> value;
    }

    if (inFile.eof())
      cout<<"End of file reached. \n";
    else if (inFile.fail())
      cout<<"Input Terminated by data mismatch.\n";
    else
      cout<<"input terminated for unknown reason";

    if (count == 0)
      cout<<"no data processed";
    else 
    {
      cout<<"Items read: "<<count<<endl;
      cout<<"Sum: "<<sum<<endl;
      cout<<"Average: "<<sum / count << endl;
    }
    inFile.close();
    return 0;
}

double write() 
{
    char type[81];
    char filename[81];

    cout<<"this program is more or less pointless, any text edtor on earth is better than this for writing"<<endl;
    cout<<"files; However This is the first step in learning how to create my file tranfer program."<<endl;
    cout<<"Enter the name of a file you want to create.\n";
    cin>>filename;
    ofstream outFile;
    outFile.open(filename);

    outFile<<fixed;
    outFile.precision(2);
    outFile.setf(ios_base::showpoint);
    while(!cin.fail()){
         cin.getline(type,81);
         outFile<<type<<endl;
    }

    outFile.close();
}

问题似乎是当我输入“read”时,程序会执行它应该执行的操作,直到它变为cin&gt;&gt; filename;此时我认为它将选择值赋给filename,因为程序跳过if(!inFile.is_open()){在我输入“read”之后。(我的程序的写函数工作正常。

有人可以告诉我如何解决这个问题,或者让计算机根据文本输入决定天气选择读写功能的其他方式。

我是C ++的新手,所以如果答案很简单,我将不胜感激,谢谢。

P.S。我,在ubuntu上,如果这有所作为。

4 个答案:

答案 0 :(得分:0)

你可以使用cin.ignore(INT_MAX);在cin.getline(filename,size)之前清除输入缓冲区;

答案 1 :(得分:0)

问题是您没有从输入流中读取“EOL序列”(AKA'\ n'):

cin>>choice;

这只读一个字。但是没有从输入中读取'\ n'字符 所以下面写着:

cin.getline(filename, size);

只读取您在上次读取后留在流上的'\ n'字符(而不是您期望的下一行)。

阅读用户输入时 我总是喜欢阅读输入行,然后在内部处理它。

std::string  command;
std::getline(std::cin, command); // reads the whole line (but discards the '\n')

if (command == "read") { /* Stuff */ }

然后您获取文件名的代码应该有效:

std::string  filename;
std::getline(std::cin, filename);

std::ifstream(filename.c_str());

全部完成。

我们在这里时: 这很聪明,因为你可以避免在流上循环的正常问题 但是有一个更好的解决方案(更好的意思是更紧凑):

inFile >> value;
while(inFile.good()) 
{
  cout<<value<<"\n";
  ++count;
  sum += value;
  inFile >> value;
}

试试这个:

while(inFile >> value) 
{
  cout<<value<<"\n";
  ++count;
  sum += value;
}

技巧2:更喜欢在固定大小的char缓冲区上使用std :: string。

答案 2 :(得分:0)

你只需要调和你对“cin&gt;&gt;”的使用当您想要读取字符串时,与“getline”相对。他们的行为略有不同。

请记住,当使用cin从控制台读取时,用户触摸的每次击键都会进入cin缓冲区,包括返回键的\ n 。< / p>

因此,当您的用户输入“read”并点击返回以输入他们的选择时,此时cin的内容为:

读\ n

然后你做:

string choice;
cin >> choice;

问题是>>运算符被定义为在它到达空格之前读取,因此它将以“read”读取,但是它将保留\ n仍然位于cin缓冲区中。< /强>

因此,在cin >> choice语句后,cin的内容为:

\ n

然后你去做:

char filename[size];
cout<<"Enter the name of the file you want to read \n";
cin.getline(filename, size);

这里的问题是>>运算符被定义为读取直到空格(如\ n),但getline被定义为读取直到它到达\ n和它将读取该行上的所有内容,直到它看到\ n ,然后读取\ n并将其丢弃。

您的问题是,当您到达cin.getline(filename,size)语句时,cin缓冲区中仍然会有一个\ n字符,因此getline会立即看到\ n并将其丢弃,将空字符串存储到filename


你有几个选择。

如果您将文件名设为字符串并将文件名更改为:

cin >> filename;

它将正常工作,因为>>运算符也会忽略前导空格。

您还可以将choice的初始读取更改为此类(使用此处字符串标题中的getline):

string choice;
getline(cin,choice);

这样做会有效,因为getline不会将迷路\ n字符留在cin缓冲区中。

您可以使用cin.ignore功能擦除cin缓冲区。如果你不知道自己在做什么,你不想盲目地使用ignore,但在这种情况下我们知道你在cin上留下了一个流浪者,所以如果你想摆脱它,你可以这样做:

#include <limits>

string choice;
cin >> choice;
cin.ignore(std::numeric_limits<int>::max(),'\n');

ignore语句基本上擦除cin中的剩余数据,说“丢弃下一个INT_MAX字符或所有内容直到并包括\ n。”

希望清除正在发生的事情。

答案 3 :(得分:0)

谢谢大家;我通过将此包含放在源文件的顶部,使用brent nash找到了我的答案;

(#)包括

并将此代码放在我的cin&gt;&gt;选项之后;

cin.ignore(标准:: numeric_limits :: MAX(), '\ n');

我会查看其他答案;