我正在运行以下程序。我在B.txt
中获取前63个字符值,然后将A.txt
中的浮点值附加到A.txt
的第62列开始,位于B.txt
行的末尾}
所以如果B.txt包含:
I am running the following program below. I am taking the firstXXXXXXXX
和A.txt包含:
I am running the following program below. I am taking the fir3.14
我希望B.txt看起来像:
I am running the following program below. I am taking the first3.14
然而,我得到的输出是:
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);
}
答案 0 :(得分:2)
strncpy
是一个糟糕的功能。这是因为如果输入不适合缓冲区,它不会对输出进行空值终止。您看到的垃圾是将非空终止缓冲区传递给期望以null结尾的字符串的函数的结果。
最简单的解决方法是替换:
char buffer[64];
strncpy(buffer, line, 63);
使用:
std::string buffer = line;
buffer.resize(63);
在您的其他用法中,您执行null-terminate,但是您永远不会检查len
是否小于80
。同样,更简单的解决方案是:
std::string buffer( line + pos, len );
sscanf(buffer.c_str(), "%f", d);
getFloat
函数应该有一些信号错误的方法(返回值;如果sscanf
没有返回1
则抛出异常)。
当然,你也可以用C ++风格的代码替换很多其他C风格的代码,并完全避免缓冲区大小问题。