【问题标题】:Saving text from text file as multiple variable types将文本文件中的文本保存为多种变量类型
【发布时间】:2016-05-04 09:25:26
【问题描述】:

目前正在尝试从文本文件中存储一些信息,文本文件的格式为数字/文本/文本/数字,我想将它们分别保存为int、string、string和float。在文件中,它们实际上由 / 分隔,因此文本文件的示例可能类似于 173/hello/goodbye/13.4

这是我目前的代码

    int main(){

    string menuname;
    int a;
    float d;
    string b;
    string c;
    bool error = false;
    ifstream openFile;

    do{
        cout  << "Please enter the name of the menu you would like to open: ";
        cin >> menuname;
        menuname +=  ".txt";

        openFile.open(menuname.c_str());
        if(openFile.fail()){
            cerr << "Unable to open file, please re-enter the name.\n";
            error = true;
        }
    }while(error == true);

    openFile >> a;
    openFile >> b;
    openFile >> c;
    openFile >> d;
    cout << itemno << category;
    }

我不是 100% 确定导致问题的原因,但我感觉这可能与字符串有关,好像我只是使用 openFile &gt;&gt; a; 和下一个 3 它正确显示,但在添加 @ 之后987654324@it 显示整行,而不仅仅是旁边的单词/短语。

【问题讨论】:

标签: c++ string output


【解决方案1】:

不要将operator&gt;&gt; 用于格式化字符串输入。它非常贪婪地读取字符串。

如果您有自定义分隔符,则首选getline() 分隔字符串。

然后将它们格式化为正确的数据类型。

【讨论】:

  • 我正在考虑使用getline() 进行尝试,但我对编程还不是很先进,并且不确定没有 / 是否会导致问题,就像我完成程序时一样它有望读取多个不同的行并以相同的格式分别保存它们。
  • @Thecube 你应该将'/'作为分隔符传递给getline。这很简单,如果您遇到麻烦,您可以随时在 SO 上提出其他问题。
  • 好的,对于第一行的最后一个变量,它后面没有/,那么将分隔符作为白人的步伐在那里工作吗?
  • 当使用getline()时,是否可以存储int和float,还是只能存储字符串?
  • @Thecube,如果您希望最后一个分隔符成为换行符(这是默认分隔符),则无需传递任何内容。 getline 仅适用于字符串。解压后即可解析字符串。
【解决方案2】:

使用 getline() 并添加分隔符 '/' 可以解决此问题,但当您使用它读取文本文件时,将读取的值默认为字符串类型。您必须通过使用 cstdlib 的函数将其转换为 int 和 float 作为您的程序想要的,对于 int 的 atoi() 和对于 double/float 的 atof()。请看下面的代码:

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

using namespace std;

int main()
{
	string menuname;

	string a, b, c, d;

	bool error = false;
	ifstream openFile;

	do
	{
		cout << "\n Please enter the name of the menu you would like to open: ";
		cin >> menuname;
		menuname += ".txt";

		openFile.open(menuname.c_str());

		if (openFile.fail())
		{
			cerr << "\n Unable to open file, please re-enter the name.\n";
			error = true;
		}
	} while (error == true);

	cout << endl;

	getline(openFile, a, '/');
	getline(openFile, b, '/');
	getline(openFile, c, '/');
	getline(openFile, d, '/');

	int aNum = atoi(a.c_str());
	float dNum = atof(d.c_str());

	cout << " " << a << " " << b << " " << c << " " << d;
	cout << "\n Trying to add an int and a double: " << aNum + dNum;

	return 0;
}

我创建的文本文件包含: 123/你好/再见/12.3

它会输出:

123 Hello Goodbye 12.3 
Trying to add an int and a double: 135.3

我也是 C++ 新手,如果有人发现我编辑的代码有问题,请纠正我。

【讨论】:

  • 是的,您的答案需要一点帮助,因为没有尾随分隔符。对输入进行测试:“1/one/one/1.0\n2/two/two/2.0”注意d 将包含:“1.0\n2”。此外,您只是阅读strings,告诉他如何处理上述内容,但如果您要提供示例,至少要完整。您似乎来自 JavaScript,您没有插入 JavaScript,因此请从您的答案中删除这些标签。您可以在 my answer 中查看正确的方法。
  • 谢谢,我想我正在让getline() 工作,虽然现在我有多行并试图将它存储在一个数组中,但我目前正在使用for (int i = 0; i &lt; 5; i++){ getline( openFile, a[i], ':');,这似乎是当我输出 a[i] 数组时什么都不做
【解决方案3】:

提取操作符通常只在提取对象时使用。如果那是您实际在做的事情,请告诉我,我将编辑此答案。

您可以通过使用尾随分隔符来简化您的输入,然后您可以为每个输入使用getline。但事实上,我们仍然可以解决您所拥有的问题:

openFile >> a; // There is no leading delimiter, and the delimiter is not numeric therefore we can simply use the extraction operator
openFile.ignore(numeric_limits<streamsize>::max(), '\n'); // We must also purge the delimiter
getline(openFile, b, '/'); // This will include white spaces in b
getline(openFile, c, '/'); // This will include white spaces in c
openfile >> d; // Again using the extraction operator, but because there is no trailing delimiter no need to purge

Live Example

这种提取方法非常容错,事实上我认为它唯一不能处理的是转义分隔符。如果您需要支持,请告诉我,但那时我倾向于使用regex_token_iterator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    相关资源
    最近更新 更多