1

我是一个菜鸟 C++ 学生。我无法将文件读入数组结构。这是一项课堂作业,所以我不需要任何人为我编写代码,我只想知道我做错了什么。我正在阅读的文本文件格式如下:

Giant Armadillo#443#M
Hawaiian Monk Seal#711#M 
Iberian Lynx#134#M
Javan Rhinoceros#134#M etc...

usinggetline()可以正确读取带有'#'分隔符的字符串,但不适用于intchar. 如何在检查分隔符时读取int或?char谢谢,对不起,如果这不是写清楚,或格式不正确。我对SO是全新的。

#include <iostream>
#include<string>
#include <fstream>
#include <cstdlib>
using namespace std;

//Create a new structure
struct Endangered
{   
    string name;
    int population; 
    char species;
};


int main () {

Endangered animals[200];

//initialize animals
for (int i=0; i<50; i++)
{
    animals[i].name=" ";
    animals[i].population=0;
    animals[i].species=' ';
}

ifstream myFile;
myFile.open("animals.txt");
int i=0;
if (myFile.is_open())
{   
    while (myFile.eof())
    {   
        //read the string until delimiter #
        getline(myFile, animals[i].name, '#');

        //read the int until delimiter #
        getline(myFile, animals[i].population, '#');

        //read the char until the delimiter
        getline(myFile, animals[i].species, '/n');
        i++;
    }


    return 0;
}
4

4 回答 4

0

我确定您不能像这样从文件中读取数据:

//read the int until delimiter #
getline(myFile, animals[i].population, '#');

因为你有刺痛,你想把它分配给 int 或 char 字段。

看看这个声明:

istream& getline (istream& is, string& str, char delim);

您必须将字符串作为第二个参数。您不能将 int 或 char 传递给此函数,而 animals[i].population 是 int 类型。

您应该首先将数据加载到某个字符串或 char* 缓冲区,然后使用正确的函数将其转换为您想要的类型。例如,寻找诸如atoi 之类的功能。

总结一下。将数据读取到临时缓冲区,然后进行转换。

如果那对您没有帮助,我会更正代码,但您不想这样做:)

于 2013-04-05T07:04:55.283 回答
0

程序的读取部分可能如下所示:

size_t i=0;
ifstream myFile("animals.txt");
if(!myFile)
{
  throw std::runtime_error("Failed opening file");   
}
string line;
while(std::getline(myFile, line))
{
  istringstream line_stream(line);
  string temp;
  if(!std::getline(line_stream, temp, '#'))
    throw std::runtime_error("expected #");
  animals[i].name = std::stoi(temp);

  if(!std::getline(line_stream, temp, '#'))
    throw std::runtime_error(expected #");

  animals[i].population = std::stoi(temp);

  if(!std::getline(line_stream, temp) || temp.size() != 1) // or whatever input verification you need
    throw std::runtime_error("expected species");
  animals[i].species = temp[0]; // or whatever input you need, this assumes species is a char
}

有一些方法没有在这里完成所有缓冲,但这应该可行。

于 2013-04-05T07:13:27.827 回答
0

问题在于 getLine 函数将下一个分隔值作为字符串返回: Function def: getline (istream& is, string& str, char delim);

更改代码以将值读入临时字符串变量。

然后使用 std::stoi( str ) 将字符串值转换为整数并将返回的值分配给人口。

您要求不提供任何代码,所以我将把实现留给您。

希望这可以帮助。

于 2013-04-05T07:13:54.860 回答
-1

这里有两个问题:读取非空格分隔的文本(包含空格的字符串)和将文本转换为数字。

快速而肮脏的方法可以是:

for(int i=0; myFile && i<sizeof(animals)/sizeof(Endangered); ++i)
{   
    char delim = 0; 

    //read the string until delimiter #
    getline(myFile, animals[i].name, '#');

    //read the int 
    myfile >> animals[i].population;
    //read and check delimiter
    if(myfile>>delim && delim!='#') mifile.setstate(myfile.failbit);

    //read the species
    myfile >> animals[i].species;

    //discard any other rubbish untile the end of line
    myfile.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
    myfile >> delim; // this is '\n';
}

注意:

  • 我使用 for (not while) 以便一起定义计数器 ( i) 及其增量 ( ) (nmo 风险忘记了)。++i

  • 退出条件不是 myfile.eof() (当它发生时已经太晚了),只是myfile(如果“可读”,它可以自行转换为“true”:如果文件变得不可读,则退出,无论发生什么错误,即使还没有结束)

  • 另一个退出条件(在 && 与第一个)是数组已被完全填充(表达式只是它的大小,不管它是什么)

    • 第一个字符串(可能包含空格)被读取到 '#' (读取,但不存储,就像你需要的那样)

    • 数字被读取为输入字段(如果没有数字,>>运算符将设置失败位,您将不再阅读并安全退出)

    • 分隔符被读取为输入字段:数字之后和 # 之前的任何空格都将被丢弃。# 进入delim,如果我们发现它不是 #,我们设置故障位(文件不包含应该包含的内容)并阻止任何读取并安全地退出循环(myfile 将评估为假)。

    • 每个最终的空格都被丢弃,下一个字符进入species.

    • 现在让我们丢弃任何最终保留在行上的东西(包括'\n')。

    • 我们现在可以继续下一行。

请注意,if不需要您的包装:如果 myfile 没有打开,它评估为“false”并且不会进入循环。

此处的 eof() 条件不能被视为“终止的失败”,而是“达到的成功”。

如果 -after the loop-file.eof() 为真,则您已成功读取所有内容,否则您会因错误而过早停止。

另请注意,整个for主体可以是名为的函数的主体

std::isream& operator>>(std::istream& myfile, Endangered& endangered)
{
  .....
  .....
  return myfile;
}

并且循环将只是

for(int i=0; myFile && i<sizeof(animals)/sizeof(Endangered); ++i)
   myfile >> animals[i];
于 2013-04-05T07:42:36.257 回答