![](/img/trans.png)
[英]C++ - I read a whole file (_which is a list of words separated by 2 white spaces_), how do i get the words separately fast?
[英]How do I read in a text file separated by spaces into an array in c++?
我有一個名為 InputFile.txt 的數字文本文件。 該文件如下所示:
10.5 73.5 109.5 87 45 108 66 117 34.5 13.5 60 97.5 138 63 130.5 4.5 40.5 43.5 60 18
我想讀取這個文件並將每個單獨的數字作為數組 arr 的一個元素插入。 我知道我沒有嘗試將元素添加到數組中,但我不確定我將如何處理這個問題。 任何建議將不勝感激。
int main(int argc, char* argv[]) {
float array[20];
ifstream file("InputFile.txt");
}
這是這樣做的一種方法,雖然有點先進。
以下使用std::copy
std::istream_iterator<float>
使用std::copy
。 請注意使用 vector 的靈活性:
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
int main(int argc, char* argv[])
{
std::vector<float> values;
std::ifstream file("InputFile.txt");
// read the input
std::copy(std::istream_iterator<float>(file),
std::istream_iterator<float>(), std::back_inserter(values));
// print out the results of the input read
for (auto f : values)
std::cout << f << "\n";
}
我已經為這個問題提供了 2 個解決方案。 下面的程序從 input.txt 讀取double
並且如果文件中有一些無效條目可以說有一些string
那么它將跳過該字符串並讀取下一個值並且只有當該值有效時( double
)它才會把它根據需要進入數組。
解決方案 1 :使用內置數組
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main()
{
std::string line;
std::ifstream inFile("input.txt");
//in case of using array, size must be fixed and predetermined
double arr[20] = {0.0}; //you can choose size according to your needs
if(inFile)
{
double i = 0;//this variable will be used to add element into the array
int count = 0;
while(getline(inFile, line, '\n'))
{
std::istringstream s(line);
//take input(from s to i) and then checks stream's eof flag status
while(s >> i || !s.eof()) {
//check if either failbit or badbit is set
if(s.fail())
{
//clear the error state to allow further operations on s
s.clear();
std::string temp;
s >> temp;
continue;
}
else
{
arr[count] = i;
++count;
//break out of the loop so that we don't go out of bounds
if(count >= 20)
{
break;
}
}
}
}
}
else
{
std::cout<<"file could not be read"<<std::endl;
}
inFile.close();
for(double i: arr)
{
std::cout<<"elem: "<<i<<std::endl;
}
return 0;
}
可以在此處檢查解決方案 1 的輸出。
解決方案 2 :使用std::vector
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main()
{
std::string line;;
std::ifstream inFile("input.txt");
std::vector<double> vec;
if(inFile)
{
double i = 0;//this variable will be used to add element into the vector
while(getline(inFile, line, '\n'))
{
std::istringstream s(line);
//take input(from s to i) and then checks stream's eof flag status
while(s >> i || !s.eof()) {
if(s.fail())
{
//clear the error state to allow further operations on s
s.clear();
std::string temp;
s >> temp;
continue;
}
else
{
vec.push_back(i);
}
}
}
}
else
{
std::cout<<"file could not be read"<<std::endl;
}
inFile.close();
for(double i: vec)
{
std::cout<<"elem: "<<i<<std::endl;
}
return 0;
}
解決方案 2 的輸出可以在這里看到。
即使 input.txt 文件中存在無效輸入(如字符串),這兩個版本也能正常工作。 正如你在這里看到的,input.txt 文件在數字之間有字符串。 該程序只是跳過那些無效的輸入並讀取下一個內容。 如果接下來的東西是雙倍的,它會將那個東西/值放入向量/數組中。
使用std::vector
優於內置數組(在這種情況下)的優點是您事先不知道向量的大小。 所以最好是因為你不知道 input.txt 文件中有多少個整數。 std::vector
可以正確/動態地處理這個。 但是在使用內置數組時,您必須事先知道/指定數組的大小。 這反過來意味着您必須事先知道 input.txt 中有多少個整數,這是不切實際的。
如果需要使用浮點數數組,可以使用不太高級的方法將行讀入字符串,從字符串創建字符串流,然后從字符串流中提取浮點數。
使用 POA(plain-old-array),您有責任確保不超出數組邊界進行寫入。 為確保您不會嘗試向數組寫入超過其所能容納的元素,只需保留一個計數器,您可以使用它來索引數組並針對數組可以容納的最大元素數進行驗證。
一個簡短的例子是:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#define MAXF 20 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
std::ifstream file;
std::string str{};
float array[MAXF] = {0};
if (argc < 1) { /* validate filename provided as argument */
std::cout << "usage: ./prog file with space separated floats\n";
return 1;
}
file.open (argv[1]); /* open file */
if (!file.is_open()) { /* validate file is open for reading */
std::cerr << "error: file open failed.\n";
return 1;
}
while (getline (file, str)) { /* read each line */
std::istringstream iss (str); /* create stringstream */
float f;
size_t nfloats = 0; /* count of no. of floats */
while (nfloats < MAXF && iss >> f) { /* protect bound, get float */
array[nfloats++] = f; /* add float to array */
}
for (size_t i = 0; i < nfloats; i++) { /* output floats from line */
std::cout << array[i] << '\n';
}
}
}
(注意:這將讀取文件中包含的多行浮點數,重新使用相同的數組來保存每行中的浮點數,然后在讀取下一行之前打印浮點數)
備選方案 2
您還可以讀取字符串並使用交替調用.find_first_not_of()
以跳過空格並保存浮點值的開始位置,然后使用.find_first_of()
查找並保存下一個位置值后的空格。 (您需要檢查npos
以確定最后一個值)。 然后您將調用stof()
進行轉換並處理轉換失敗時的任何異常。
這一切都強調了為什么使用 C++ 提供的細節以及@PaulMcKenzie 展示的更“高級方法”可以減少您的代碼大小,並消除您必須執行的手動檢查、索引和邊界保護。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.