我是一名noob C ++学生。我在将文件读入数组结构时遇到问题。这是一个类赋值,所以我不需要任何人为我做代码,我只想知道我做错了什么。我正在阅读的文本文件格式如下:
Giant Armadillo#443#M
Hawaiian Monk Seal#711#M
Iberian Lynx#134#M
Javan Rhinoceros#134#M etc...
使用getline()
可以正确读取带有'#'
分隔符的字符串,但无法使用int
或char
。检查分隔符时如何阅读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;
}
答案 0 :(得分: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是typeof int。
您应首先将数据加载到某个字符串或char *缓冲区,然后使用正确的函数将其转换为您想要的类型。寻找像 atoi 这样的功能。
总结一下。将数据读取到临时缓冲区然后转换它。
如果这对您没有帮助,我会更正代码,但您不想:)
答案 1 :(得分: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
}
有一些方法可以在这里完成所有缓冲,但这应该有效。
答案 2 :(得分:0)
问题是getLine函数以字符串形式返回下一个分隔值: 函数def:getline(istream&amp; is,string&amp; str,char delim);
更改代码以将值读入临时字符串变量。
然后使用std :: stoi(str)将字符串值转换为整数,并将返回的值分配给population。
您要求不提供任何代码,因此我会将实施交给您。
希望这有帮助。
答案 3 :(得分:-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';
}
请注意:
我用于(而不是while),以便计数器(i
)及其增量(++i
)一起定义(冒险忘记)。
退出条件不是myfile.eof()(当它发生时已经太晚了),只有myfile
(如果“可读”它可以自我转换为“true”:你退出,如果文件变得不可读,无论出现什么错误,即使还没有结束)
另一个退出条件(&amp;&amp; with first)是数组已被完全填充(表达式只是它的大小,无论它是什么)
第一个字符串(可能包含空格)被读取为'#'(即读取,但不存储,就像您需要的那样)
该号码被视为输入字段(如果没有号码,&gt;&gt;运算符将设置failbit,您将不再阅读并安全退出)
分隔符被读作输入字段:数字后面和#被丢弃之前的任何空格。 #进入delim
,如果我们发现它不是#,我们设置failbit(文件不包含应该包含的内容)并阻止任何读取并安全地退出循环(myfile wil evaluateas false)
每个最终空格都会被丢弃,下一个字符会进入species
。
现在让丢弃的东西最终留在线上(包括'\ n')。
我们现在可以继续下一行了。
请注意,不需要包装if
:如果myfile未打开,则评估为“false”,并且不会输入循环。
这里的eof()条件不能被视为“终止失败”,而是“达到成功”。
如果 - 在loop- file.eof()为true之后,您成功读取了所有内容,否则由于错误而提前停止。
另请注意,整个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];