我想要做的是从文本文件中读取一行,其中包含一个长度为< = 20且两个整数的双字符串,例如它可能如下所示:
Name Surname 1 14
我知道如果我读取字符串,字符串将是所有字符,直到空格,但getline()将整行读作字符串。那我怎么读这样的一行呢?有没有简单的方法,或者我将不得不使用正则表达式?
答案 0 :(得分:6)
也许......
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream file( "/home/facu/text.txt", ios::in );
string part1, part2;
int num1, num2;
if( !file )
cerr << "Cant open " << endl;
while( file >> part1 >> part2 >> num1 >> num2 )
{
cout << part1 << " " << part2 << " " << num1
<< " " << num2 << endl;
}
file.close();
return 0;
}
text.txt:
JONES JONES 12 14
MICHAEL MICHAEL 12 100
DOE DOE 15 20
答案 1 :(得分:2)
std::getline()
可能是最好的功能。然后创建一种形式的解析器,用空格分隔每个字段。从那里,您可以使用std::stringstream
将字段(在本例中为2和3,如果从0开始)转换为整数值。您显然希望对任何类型的I / O操作进行某种错误处理。
编辑:以下是我帮助您入门的示例
// Example
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#define FIELD_SIZE 4 // How many fields per line
// This is just a custom data structure to hold the data you want
struct myInfo
{
myInfo(){} // Default ctor
myInfo(std::string name1,std::string name2,int n1,int n2) // Ctor accepting all data
: first(name1), last(name2), num1(n1), num2(n2) {}
std::string first, last;
int num1,num2;
};
// Get the initial size of what your array should be
// This is based on how many '\n's are found
int getNumLines(const std::string& input)
{
int retval = 0;
for(unsigned int i=0;i<input.length();++i)
if(input[i] == '\n')
retval++;
return retval;
}
// Convert string to int
int convertStringToInt(const std::string& input)
{
std::stringstream ss(input);
int retval;
ss >> retval;
return retval;
}
// Parse input and store it in our structure
// Not really efficient if you have large datasets to work with
void parseAndStore(std::string input, myInfo *& myArray, int size)
{
size_t pos = 0, pos2 = 0; // Temporary position holder
std::string first, last, tmp1, tmp2;
std::stringstream tmp;
int num1, num2;
// This is not efficient - it's merely an example
for(int i=0;i<size;++i) // How many items to insert
for(int j=0;j<FIELD_SIZE;++j) // How many fields
{
if(j < FIELD_SIZE-1)
{
pos2 = input.find(" ",pos+1);
if(pos2 == std::string::npos || pos2 > input.find('\n',pos)) // Don't run over the next line
{
pos = input.find('\n',pos); // Next line
break; // Error - invalid line format
}
// Relatively hacky, but this is just an example to give you an idea
switch(j)
{
case 1:
last = input.substr(pos,pos2-pos);
break;
case 2:
tmp1 = input.substr(pos,pos2-pos);
break;
default:
first = input.substr(pos,pos2-pos);
break;
}
pos = pos2+1;
} else { // All data collected - parse our ints and store it in our structure
pos2 = input.find('\n',pos); // End of line
tmp2 = input.substr(pos,pos2);
// Convert
num1 = convertStringToInt(tmp1);
num2 = convertStringToInt(tmp2);
// Insert it into our array
myArray[i] = myInfo(first,last,num1,num2);
pos = pos2+1; // Advance position
}
}
}
int main()
{
// Read your input file - this is just an example
std::string input("Joe Serma 1 30\nGeorge Hola 2 17\n");
int size = getNumLines(input); // Parse the number of lines in your input
myInfo * myArray = new myInfo[size]; // Allocate a dynamic array to store your data
parseAndStore(input,myArray,size); // Parse this string - leave the original in tact though
// Print contents of the array
for(int i=0;i<size;++i)
{
std::cout<< std::endl << "=== Person "<< i+1 << "===" << std::endl
<< "First: "<< myArray[i].first << std::endl
<< "Last: "<< myArray[i].last << std::endl
<< "Num1: "<< myArray[i].num1 << std::endl
<< "Num2: "<< myArray[i].num2 << std::endl
<< "Num1+Num2 (For confidence of true int): "<< myArray[i].num1+myArray[i].num2 << std::endl;
}
delete [] myArray; // Cleanup
return 0;
}
的问候,
丹尼斯M。