我在下面运行以下程序。我在 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/