读取文件后提取子向量时出现C ++错误

时间:2016-11-26 00:21:47

标签: c++ file vector

我正在读取文件并从中创建向量,之后我尝试按如下方式提取子向量:

http: panic serving [::1]:50178: runtime error: invalid memory address or nil pointer dereference
goroutine 35 [running]:
net/http.(*conn).serve.func1(0xc420166400)
    /usr/local/opt/go/libexec/src/net/http/server.go:1491 +0x12a
panic(0x396220, 0xc42000c0b0)
    /usr/local/opt/go/libexec/src/runtime/panic.go:458 +0x243
gopkg.in/gin-gonic/gin%2ev1.(*Engine).ServeHTTP(0x0, 0x5a7c80, 0xc4201ec0d0, 0xc4200f0870)
    /Users/juanma/.go/src/gopkg.in/gin-gonic/gin.v1/gin.go:260 +0x26
net/http.serverHandler.ServeHTTP(0xc420166380, 0x5a7c80, 0xc4201ec0d0, 0xc4200f0870)
    /usr/local/opt/go/libexec/src/net/http/server.go:2202 +0x7d
net/http.(*conn).serve(0xc420166400, 0x5a83c0, 0xc420174440)
    /usr/local/opt/go/libexec/src/net/http/server.go:1579 +0x4b7
created by net/http.(*Server).Serve
    /usr/local/opt/go/libexec/src/net/http/server.go:2293 +0x44d
http: panic serving [::1]:50179: runtime error: invalid memory address or nil pointer dereference
goroutine 36 [running]:
net/http.(*conn).serve.func1(0xc420166600)
    /usr/local/opt/go/libexec/src/net/http/server.go:1491 +0x12a
panic(0x396220, 0xc42000c0b0)
    /usr/local/opt/go/libexec/src/runtime/panic.go:458 +0x243
gopkg.in/gin-gonic/gin%2ev1.(*Engine).ServeHTTP(0x0, 0x5a7c80, 0xc420214000, 0xc4200f0960)
    /Users/juanma/.go/src/gopkg.in/gin-gonic/gin.v1/gin.go:260 +0x26
net/http.serverHandler.ServeHTTP(0xc420166380, 0x5a7c80, 0xc420214000, 0xc4200f0960)
    /usr/local/opt/go/libexec/src/net/http/server.go:2202 +0x7d
net/http.(*conn).serve(0xc420166600, 0x5a83c0, 0xc420174600)
    /usr/local/opt/go/libexec/src/net/http/server.go:1579 +0x4b7
created by net/http.(*Server).Serve
    /usr/local/opt/go/libexec/src/net/http/server.go:2293 +0x44d

在这种情况下,代码可以工作,我只是从原始向量中删除第一个特征,我也可以这样做:

vector<double> v = {1, 2, 3, 4, 5};
displayVector(v);
vector<double> v2(&v[1], &v[v.size()]);
displayVector(v2);

也给了我想要的输出,但对于我的应用程序来说,第一种方式很有趣。

这里的问题是我从文件中读取并构建向量。这样的文件看起来像这样:

v.erase(v.begin());

第一个坐标对我来说不感兴趣,这是我的代码:

1000025,5,1,1,1,2,1,3,1,1,2
1002945,5,4,4,5,7,10,3,2,1,2
1015425,3,1,1,1,2,2,3,1,1,2
1016277,6,8,8,1,3,4,3,7,1,2
1017023,4,1,1,3,2,1,3,1,1,2
1017122,8,10,10,8,7,10,9,7,1,4
1018099,1,1,1,1,2,10,3,1,1,2
1018561,2,1,2,1,2,1,3,1,1,2
1033078,2,1,1,1,2,1,1,1,5,2
1033078,4,2,1,1,2,1,2,1,1,2
1035283,1,1,1,1,1,1,3,1,1,2
1036172,2,1,1,1,2,1,2,1,1,2
1041801,5,3,3,3,2,3,4,4,1,4
1043999,1,1,1,1,2,3,3,1,1,2
1044572,8,7,5,10,7,9,5,5,4,4
1047630,7,4,6,4,6,1,4,3,1,4
1048672,4,1,1,1,2,1,2,1,1,2
1049815,4,1,1,1,2,1,3,1,1,2
1050670,10,7,7,6,4,10,4,1,2,4
1050718,6,1,1,1,2,1,3,1,1,2
1054590,7,3,2,10,5,10,5,4,4,4
1054593,10,5,5,3,6,7,7,10,1,4
1056784,3,1,1,1,2,1,2,1,1,2

上面的代码编译,但是当我尝试运行它时,给我一个奇怪的错误,这是由行向量v1(&amp; v [1],&amp; v [v.size()])引起的:< / p>

void displayVector (std::vector<double> &v) {
    for (auto &feature : v) {
        std::cout << feature << " ";
    }
    std::cout << std::endl;
}

void displayTrainingSet(vector<FeaturedVector> &data) {
    for (auto a : data) {
        displayVector(a);
    }
}

int main(int argc, char const *argv[]) {

    ifstream file;
    string filename = "breast-cancer.data";

    file.open(filename, std::ifstream::in);

    vector<FeaturedVector> data;

    while (file.good()) {
        string line;
        getline(file, line);
        istringstream buffer(line);

        double feature;
        vector<double> v;

        while (buffer >> feature) {
            if (buffer.peek() == ',') {
                buffer.ignore();
            }
            v.push_back(feature);
        }

        vector<double> v1(&v[1], &v[v.size()]);
        data.push_back(v1);
    }

    file.close();

    //displayTrainingSet(data);
    return 0;
}

有人知道为什么会这样吗?我知道从文件中读取并创建矢量v是有效的,因为我已经尝试在屏幕上显示矢量并且工作正常。在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

getline(file, line);

当此代码读取文件的最后一行时,将读取文件中的最后一个字符(最终换行符)。代码会从此时开始,但file 设置eof。只有在尝试从文件读取因文件结束而失败后才会设置eof位。

这还没有发生。 getline()仅读取文件中的最后一个字符,即最终换行符,并停止。

在循环的下一次迭代中:

while (file.good()) {

这将成功。正如我所解释的那样,eof标志尚未设置。

    string line;
    getline(file, line);

现在无法从文件中读取任何内容,在文件上设置eof位。 line将是一个空字符串。

由于line现在为空,内部while循环不会提取任何内容,

vector<double> v;

将仍为空载体。

vector<double> v1(&v[1], &v[v.size()]);

鉴于v现在是一个空向量,v.size()将为0,那么你认为现在会发生什么呢?

答案 1 :(得分:0)

I modified your code a little bit to compile on my machine. i can display the data on your sample file.

#include <vector>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

void displayVector (std::vector<double> &v) {
    for (auto &feature : v) {
        std::cout << feature << " ";
    }
    std::cout << std::endl;
}

void displayTrainingSet(std::vector< std::vector<double> > &data) {
    for (auto a : data) {
        displayVector(a);
    }
}

int main(int argc, char const *argv[]) {

    ifstream file;
    string filename = "C:/temp/2.txt";

    file.open(filename, std::ifstream::in);

    vector< vector<double> > data;

    while (file.good()) {
        string line;
        getline(file, line);
        istringstream buffer(line);

        double feature;
        vector<double> v;

        while (buffer >> feature) {
            if (buffer.peek() == ',') {
                buffer.ignore();
            }
            v.push_back(feature);
        }

        vector<double> v1(&v[1], &v[v.size()]);
        data.push_back(v1);
    }

    file.close();

    displayTrainingSet(data);
    return 0;
}