简体   繁体   English

使用strncpy的ofstream中的垃圾值

[英]Junk values in ofstream using strncpy

I am running the following program below. 我正在下面运行以下程序。 I am taking the first 63 char values in B.txt and then attaching the float values in A.txt , beginning at the 62nd column in A.txt , at the end of the lines of B.txt 我正在与第一63个char值B.txt然后附着在浮点值A.txt ,在在第62列开始A.txt ,在该线的端B.txt

So if B.txt contains: 因此,如果B.txt包含:

I am running the following program below. I am taking the firstXXXXXXXX

and A.txt contains: 并且A.txt包含:

I am running the following program below. I am taking the fir3.14

I want B.txt to look like: 我希望B.txt看起来像:

I am running the following program below. I am taking the first3.14

However, the output I'm getting instead is: 但是,我得到的输出是:

I am running the following program below. I am taking the 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 is a bad function to use. strncpy是一个不好的函数。 This is because it does not null-terminate its output if the input did not fit in the buffer. 这是因为,如果输入不适合缓冲区,它就不会使输出终止。 The garbage you are seeing is the result of passing a non-null-terminated buffer to a function that expected a null-terminated string. 您看到的垃圾是将非空终止的缓冲区传递给期望以空终止的字符串的函数的结果。

The simplest fix is to replace: 最简单的解决方法是替换:

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

with: 与:

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

In your other usage you do null-terminate, however you never check that len is smaller than 80 either. 在其他用法中,您会执行null终止,但是您绝不会检查len是否小于80 Again the simpler fix would be: 同样,更简单的解决方法是:

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

The getFloat function should have some way of signaling error (either a return value; or throw an exception if sscanf does not return 1 ). getFloat函数应该具有某种方式来指示错误(发送值;或者,如果sscanf不返回1则引发异常)。

Of course, you could replace a lot of your other C-style code with C++-style code too and avoid buffer size issues entirely. 当然,您也可以用C ++样式代码替换许多其他C样式代码,并完全避免缓冲区大小问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM