【问题标题】:not reading the first line [closed]不阅读第一行[关闭]
【发布时间】:2015-05-16 11:18:14
【问题描述】:

我正在使用以下代码将文件 (b.txt) 中的信息读取到向量中。 每次我执行时,程序都会从​​第二行开始读取。 所以 vector_b[0] = 第二行而不是第一行。

我还是不习惯 C++ 希望你能帮忙

string line_b;
int idx = -1;
float *vector_b = new float[1];
float element_b;
if (file_b.is_open() && file_b.good()) {
    cout << "File is open. \n";
    while (getline(file_b, line_b)) {
        stringstream stream_b(line_b);
        while(1) {
            stream_b >> element_b;
            if(!stream_b) {
                break; }
            idx = idx+1;
            float *tempArr = new float [idx];
            copy(vector_b, vector_b + idx, tempArr);
            tempArr[idx] = element_b;
            delete [] vector_b;
            vector_b = tempArr;
        }
    }        
    } 
    else {
        cout << "Failed to open file.";
    }

【问题讨论】:

  • 您可能需要考虑使用std::vector&lt;float&gt; 而不是new
  • 我不是很喜欢 c++ ,你能告诉我如何在上面的代码中使用 std::vector
  • 声明:std::vector&lt;float&gt; container;。提取:float a = container[3];。插入:container.push_back(3.14159264);
  • 刚刚提出我的答案。如果有什么不明白的,请告诉我

标签: c++ file vector getline


【解决方案1】:

您可以尝试以下方法。您可以尝试使用 vector 而不是动态数组。它们更灵活,在大多数情况下更快。您不必担心在释放、双重释放或内存泄漏之后使用......所以是的......向量规则......

int main() {
    std::ifstream file_b;
    file_b.open("Some-file.cpp");

    std::string line_b;
    // vector_b is a vector of doubles
    std::vector<double> vector_b();
    double element_b;
    if (file_b.is_open() && file_b.good()) {
        std::cout << "File is open. \n" << std::endl;
        while(getline(file_b, line_b)) {
            std::stringstream stream_b(line_b);
            // You don't need a second if.
            while(stream_b) {
                stream_b >> element_b;
                // append element_b to your vector
                vector_b.push_back(element_b);
            }
        }
    } else {
        std::cout << "Failed to open file." << std::endl;
    }
}

但是,如果您不能使用向量,我建议您考虑创建一个容器类,如下所示的类和用法。我不相信自己会记住释放内存,所以有时最好建立一个类。我在 valgrind 下测试了下面的类几次,所以不应该有任何泄漏,但没有任何承诺。我很着急。

#include <cassert>

// use a templated class so we can use it with different types
template<typename T>
class Container {
    private:
        unsigned int m_size;
        unsigned int m_capacity;
        T* m_array;

    public:
        // Any time you make a container class make sure you follow the
        // rule of 5 with C++11 or the rule of 3 for prior compilers
        // 1) Copy Constructor
        // 2) Move Constructor (C++11)
        // 3) Copy Assignment Operator
        // 4) Move Assignment Operator (C++11)
        // 5) Destructor

        // Default constructor
        Container() { }

        // Constructor we'll use
        Container(unsigned sz) :
            m_size(0),
            m_capacity(sz),
            m_array(new T[sz]) { }

        // Copy constructor
        Container(const Container& src) :
            m_size(src.m_size),
            m_capacity(src.m_size),
            m_array(new T[src.m_size]) {
                for(unsigned i = 0; i < m_size; ++i) {
                    // copy values
                    m_array[i] = src.m_array[i];
                }
            }

        // Move constructor
        Container(Container&& src) {
            // "steal" the sources members
            m_capacity = src.m_capacity;
            m_size = src.m_size;
            m_array = src.m_array;
            // "destroy" the sources members
            src.m_size = 0;
            src.m_capacity = 0;
            src.m_array = nullptr;
        }

        // Destructor
        ~Container() {
            delete[] m_array;
        }

        // Copy assignment operator
        Container& operator=(const Container& src) {
            // check to make sure you're copying a different source
            if(this == &src) {
                return *this;
            }
            // free your current memory
            delete[] m_array;
            // make a new array and copy the sources values
            m_array = new T[src.m_size];
            for(unsigned i = 0; i < src.m_size; ++i) {
                m_array[i] = src.m_array[i];
            }
            // copy the size parameters
            m_size = src.m_size;
            m_capacity = src.m_capacity;
            return(*this);
        }

        // Move assignment operator
        Container& operator=(Container&& src) {
            // check to make sure you're copying a different source
            if(this == &src) {
                return *this;
            }
            // free your current memory
            delete[] m_array;
            // "steal" the sources members
            m_array = src.m_array;
            m_size = src.m_size;
            m_capacity = src.m_capacity;
            // "destroy" the sources members
            src.m_array = nullptr;
            src.m_size = 0;
            src.m_capacity = 0;
            return(*this);
        }

        void resize(unsigned int sz) {
            // make sure you're not shrinking the container
            if(sz > m_capacity) {
                // make a temporary array
                T* tmp = new T[sz];
                for(unsigned i = 0; i < m_size; ++i) {
                    // copy the values to the temporary array
                    tmp[i] = m_array[i];
                }
                // free your current memory
                delete[] m_array;
                // "steal" the temporary array
                m_array = tmp;
                // release tmp's handle on the memory
                tmp = nullptr;
                // inform your object that it has more memory now
                m_capacity = sz;
            }
        }

        void push_back(const T& src) {
            // check if you have enough space to append a value
            if(m_size + 1 > m_capacity) {
                // if not, double your current size, so you don't have
                // to do it every time
                resize((m_capacity + 1) * 2);
            }
            // increment the size member and append the value to your array
            m_array[m_size++] = src;
        }

        T& operator[](unsigned index) {
            // make sure the index value is in-bounds
            assert(index < m_size);
            return(m_array[index]);
        }

        size_t size() { return(m_size); }
};

用法:

int main(int argc, char *argv[]) {
    Container<std::string> vector_b(1);
    std::ifstream file_b;
    file_b.open("Sleep.cpp");

    std::string line_b;
    std::string element_b;
    if (file_b.is_open() && file_b.good()) {
        std::cout << "File is open. \n" << std::endl;
        while(getline(file_b, line_b)) {
            std::stringstream stream_b(line_b);
                while(stream_b) {
                    stream_b >> element_b;
                    vector_b.push_back(element_b);
                }
        }
    } else {
        std::cout << "Failed to open file." << std::endl;;
    }

    for(unsigned i = 0; i < vector_b.size(); ++i) {
        std::cout << vector_b[i] << std::endl;
    }
}

如您所见,使用动态内存分配是一件痛苦的事情,通常应该避免,或者至少要格外小心并使用大量 valgrind。

【讨论】:

  • 感谢您的回答……但我只能使用“动态内存分配”。那么,我使用的代码有什么问题?
  • 我会更新答案,但老实说,如果您必须进行动态内存分配,您最好构建一个容器类,这就是我将在答案中更新的内容跨度>
  • 我做了必要的编辑。如果可行,请务必将此问题标记为已回答
  • 如果您正在使用它,您可能需要检查我的代码。我刚刚意识到我忘记在赋值运算符上使用return *this;。我进行了必要的编辑。
猜你喜欢
  • 2020-09-27
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 2020-04-02
相关资源
最近更新 更多