不读第一行

not reading the first line

本文关键字:一行      更新时间:2023-10-16

我使用以下代码将信息从文件(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.";
    }

您可以尝试如下操作。您可以尝试使用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;
    }
}

如您所见,使用动态内存分配是一种痛苦,通常应该避免,或者至少要非常小心和大量处理。