>>只能读取输入数值,不能读取输入字符或者字符串。
ifstream的>>遇到空格认为当前读取结束,比如“aa bb",如果>>到一个string,那么string变量中是aa。
getline的参数只能是char*,不能是string。
从文件中读取格式化字符串(格式化输入)sscanf,或者用正则表达式。否则,只能自己写代码,用字符串处理实现。
sscanf在vs2017中需要用sscanf_s代替。格式字符串类型说明:https://en.cppreference.com/w/cpp/io/c/fscanf
格式字符串的示例:
注意,要读取double类型的浮点数,需要用%lf。否则无法得到正确的数值。
#include
#include
#include
int main()
{
int i, j;
float x, y;
char str1[10], str2[4];
wchar_t warr[2];
std::setlocale(LC_ALL, "en_US.utf8");
char input[] = u8"25 54.32E-1 Thompson 56789 0123 56ß水";
// parse as follows:
// %d: an integer
// %f: a floating-point value
// %9s: a string of at most 9 non-whitespace characters
// %2d: two-digit integer (digits 5 and 6)
// %f: a floating-point value (digits 7, 8, 9)
// %*d an integer which isn't stored anywhere
// ' ': all consecutive whitespace
// %3[0-9]: a string of at most 3 digits (digits 5 and 6)
// %2lc: two wide characters, using multibyte to wide conversion
int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
&i, &x, str1, &j, &y, str2, warr);
std::cout << "Converted " << ret << " fields:\n"
<< "i = " << i << "\nx = " << x << '\n'
<< "str1 = " << str1 << "\nj = " << j << '\n'
<< "y = " << y << "\nstr2 = " << str2 << '\n'
<< std::hex << "warr[0] = U+" << warr[0]
<< " warr[1] = U+" << warr[1] << '\n';
}
输出结果
Converted 7 fields:
i = 25
x = 5.432
str1 = Thompson
j = 56
y = 789
str2 = 56
warr[0] = U+df warr[1] = U+6c34
while (!input.eof()) {
input >> str;
std::cout << str;
}
不会重复读取最后一行,但是会重复输出最后一次读到的内容。这是因为input完成最后一次读取后不会立即设置eof状态,所以程序会再进行一轮循环,在这轮循环input才会设置eof状态。结果就是最后一次读取的内容被输出了两次。
改为
while (input >> str) {
std::cout << str;
}
或
for(;;) {
if (!(input >> str))
break;
std::cout << str;
}
也可以考虑用getline(input, str, '\n')
来按行读取。
//调整指针位置时需要在seekg函数前加上clear函数
i = file.tellg();
file >> str1;
file.clear(); //添加clear函数
file.seekg(i);
file >> str2;