Ненужные значения в ofstream с использованием strncpy

Я запускаю следующую программу ниже. Я беру первые 63 значения символов в B.txt а затем присоединение значений с плавающей точкой в A.txtначиная с 62-го столбца в A.txtв конце строк 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

Решение

strncpy плохая функция для использования. Это потому, что он не завершает нулевой вывод, если ввод не помещается в буфер. Мусор, который вы видите, является результатом передачи буфера, не заканчивающегося нулем, в функцию, которая ожидала строку, заканчивающуюся нулем.

Самое простое решение — заменить:

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

с:

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

При другом использовании вы завершаете null, однако вы никогда не проверяете это len меньше чем 80 или. Опять более простое исправление будет:

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

getFloat у функции должен быть какой-то способ сигнализации ошибки (либо возвращаемое значение, либо выдается исключение, если sscanf не возвращается 1).

Конечно, вы можете заменить большую часть кода в стиле C на код в стиле C ++ и полностью избежать проблем с размером буфера.

2

Другие решения


По вопросам рекламы [email protected]