c++ - 使用 strncpy 的 ofstream 中的垃圾值

标签 c++ string char scanf strncpy

我在下面运行以下程序。我在 B.txt 中获取前 63 个字符值,然后在 A.txt 中附加浮点值,从 A.txt< 中的第 62 列开始,在 B.txt

行的末尾

所以如果 B.txt 包含:

我正在运行下面的程序。我要拿第一个XXXXXXXX

A.txt 包含:

我正在运行下面的程序。我走的是fir3.14

我希望 B.txt 看起来像:

我正在运行下面的程序。我先考3.14

但是,我得到的输出是:

我正在运行下面的程序。我正在服用 firstBUNCH OF JUNK3.14

int main()
{
    loadfileB("B.txt");

    return 0;
}


void loadfileB(char* fileName)
{
    FILE* fp = fopen(fileName, "r");
    char line[82];
    vector<int> rownum;
    vector<float> temp;
    temp = loadfileA("A.txt");

    int i = 0;
    ofstream fout("output.txt");

    while (fgets(line, 81, fp) != 0)
    {
        radius=temp[i];
        char buffer[64]; 
        strncpy(buffer, line, 63);
        fout << buffer<< " " << radius << endl;
        i++;
    }
    fclose(fp);
}

vector<float> loadfileA(char* fileName)
{
    FILE* fp = fopen(fileName, "r");
    char line[82];
    vector<int> rownum;
    vector <float> tempvec;

    int i = 0;
    while (fgets(line, 81, fp) != 0)
    {
        float temp;
        getFloat(line, &temp, 60, 6);
        tempvec.push_back(temp);
    }
    fclose(fp);

    return tempvec;
}

void getFloat(char* line, float* d, int pos, int len)
{
    char buffer[80];
    *d = -1;
    strncpy(buffer, &line[pos], len);
    buffer[len] = '\0';
    sscanf(buffer, "%f", d);
}

最佳答案

strncpy 是一个不好用的函数。这是因为如果输入不适合缓冲区,它不会以空值终止其输出。您看到的垃圾是将非空终止缓冲区传递给需要空终止字符串的函数的结果。

最简单的修复方法是替换:

char buffer[64]; 
strncpy(buffer, line, 63);

与:

std::string buffer = line;
buffer.resize(63);

在您的其他用法中,您执行空终止,但是您也从不检查 len 是否小于 80。同样,更简单的修复方法是:

std::string buffer( line + pos, len );
sscanf(buffer.c_str(), "%f", d);

getFloat 函数应该有某种方式来指示错误(返回值;或者如果 sscanf 不返回 1 则抛出异常).

当然,您也可以用 C++ 风格的代码替换许多其他 C 风格的代码,从而完全避免缓冲区大小问题。

关于c++ - 使用 strncpy 的 ofstream 中的垃圾值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29574590/

相关文章:

c++ - 如何检测我是否正在为 C++ 中的 64 位架构进行编译

c++ - 控制台上的 Qt 应用程序文本流

c++ - 使用绝对元素编号访问二维数组的元素

c++ - 使用 C++ 在 Mac OS X 上创建应用程序? (不含 cocoa )

php - 没有正则表达式的句子大小写

java - 从 Java 中的字符串中有效地删除特定字符(一些标点符号)?

javascript - 将字符串修改为数组

c - 这两件事有什么区别

java - 检查是否有 3 个连续的辅音

c - C指针的操作方法