为什么Utf8Char的矢量值正在变化?

时间:2016-07-07 13:13:32

标签: c++ c++11

我有一个CSVReader类,它具有此功能

vector<UtfChar*> CSVFile::ReadFile(FILE* fp)
{
    //int count = 0;
    Utf8Char buff[256];

    fgets(buff, 256, (FILE*)fp);
      //  count++;

    Utf8Char *token = strtok(buff, ",");
    bvector<UtfChar*> localVec;
    while (token != NULL)
    {
        localVec.push_back(token);
        token = strtok(NULL, ",");
    }
    return localVec;
}

现在我有了另一个类,我从中调用了这个函数:

FILE *fp;
fp = fopen("SampleFile.csv", "r");
while((getc(fp)) != EOF)
{
    bvector<Utf8Char*> localVec = csvFile.ReadFile(fp);  
}

在这里,我将localVec的值与我拥有的一组值(char*)进行比较。但是在另一个类中,当我尝试访问localVec[0]或l ocalVec[1]之类的向量时,它会产生垃圾。 我尝试在CSVReader类中进行比较,然后在那里工作。但我需要在其他类中进行比较,以便我可以为其他CSV文件使用相同的CSVReader类。

3 个答案:

答案 0 :(得分:2)

这里的问题是你有悬挂的指针。使用

创建并填充本地数组
Utf8Char buff[256];

fgets(buff, 256, (FILE*)fp);

然后使用

获取指向该缓冲区的不同段的指针
Utf8Char *token = strtok(buff, ",");
bvector<UtfChar*> localVec;
while (token != NULL)
{
    localVec.push_back(token);
    token = strtok(NULL, ",");
}

所以现在你有一个向量的指针到本地缓冲区的每个段。从函数返回向量后,本地缓冲区将被销毁。这意味着你现在拥有的所有指针都指向你不再拥有的记忆。使用这些指针是未定义的行为,这是你获得垃圾输出的原因。

另请注意,如果您使用How can I read and parse CSV files in C++?来解析CSV文件,则可以避免所有这些C-ism。

答案 1 :(得分:1)

此代码

bvector<UtfChar*> localVec;

表示您正在向量中存储指针

当函数返回时,那些指针指向一个超出范围的局部变量

答案 2 :(得分:0)

看起来你跳过从文件中读取的每个字符串中的第一个字符:

while((getc(fp)) != EOF){
    bvector<Utf8Char*> localVec = csvFile.ReadFile(fp);
}

有意吗?如果是,则问题在于:UTF-8字符可以具有可变长度(例如,一些字节用1字节表示,其他字节用2字节表示,依此类推,最多6字节)。如果不进行任何字符串转换,可以将UTF-8字符串逐字节地从一个地方复制到另一个地方,而不用担心字符长度,因为该字符串将保持有效。但是如果你从字符串中删除第一个字节,那么它就不再是一个有效的UTF-8字符串了,不能像它一样解释。