Задать вопрос
@SaddledSharp
Кодер. Увлекаюсь информационной безопасностью.

Как записать многострочный текст в файл?

Всем привет! У меня есть переменная char BUF[512] в которой хранится вывод из консоли от команды "lspci", КОД:
FILE *INFO_PC;
	char BUF[512];
	INFO_PC = popen("lspci", "r");
	if (!INFO_PC) {
		cout << "ERROR!" << endl;
	}
	else {
		while(fgets(BUF, sizeof(BUF), INFO_PC)){
			puts(BUF);
		}
	}

Мне нужно эту переменную BUF записать в текстовый файл. Но когда я пишу:
FILE *INFO_PC;
	char BUF[512];
	INFO_PC = popen("lspci", "r");
	if (!INFO_PC) {
		cout << "ERROR!" << endl;
	}
	else {
		while(fgets(BUF, sizeof(BUF), INFO_PC)){
			puts(BUF);
		}
	}
	FILE *FILE_INFO_PC = fopen("desktop.cfg", "w");
	if (FILE_INFO_PC) {
		bool write = fputs(BUF, FILE_INFO_PC);
		if (write) {
			cout << "Yes!" << endl;
		}
		else {
			cout << "ERROR!" << endl;
		}
	}
	else {
		cout << "ERROR!" << endl;
	}
	fclose(FILE_INFO_PC);

То после выполнения в файл записывается только первая строка, а именно -
03:00.0 3D controller: NVIDIA Corporation GK107M [GeForce 810M] (rev a1)

Сам же вывод содержится из 5 строк, но записывается только одна. Как правильно написать?
  • Вопрос задан
  • 319 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 2
while(fgets(BUF, sizeof(BUF), INFO_PC)){
   puts(BUF);
}

Этот цикл построчно вычитывает выхлоп от `popen(...)`. Не удивительно, что в BUF остается лишь одна последняя строка.

И еще вижу возможную утечку в случае ошибки popen(...): `char BUF[512]` ничем не инициализирован и все, что лежит на стеке может улететь в desktop.cfg.
Ответ написан
myjcom
@myjcom Куратор тега C++
SaddledSharp, тегом не ошиблись?
++

под Win но разница только в путях и _popen -> popen _pclose -> pclose
#include<iostream>
#include<fstream>
#include<algorithm> // copy
#include<string>
#include<vector>
#include<array>
#include<memory> // unique_ptr
#include<cstdio>
#include<iterator>

using namespace std;
using pipe = unique_ptr<FILE, decltype(&_pclose)>;

auto getCmdOutput = [](const string& command)
{
  pipe fp{_popen(command.c_str(), "r"), &_pclose};
  vector<string> result;
  array<char, 512> buf;
  if(fp)
  {
    while(fgets(buf.data(), buf.size(), fp.get()))
    {
      result.emplace_back(buf.data());
      buf.fill(0);
    }
  }
  return result;
};

auto writeToFile = [](const string& fname, const vector<string>& info)
{
  ofstream ofs(fname);
  if(info.empty() || !ofs)
  {
    // put error ... 
    return false;
  } 
  copy(info.cbegin(), info.cend(), ostream_iterator<string>{ofs});
  return true;
};

int main()
{
  if(writeToFile("D:\\ipconfig.cfg", getCmdOutput("ipconfig")))
  {
    cout << "Success!" << endl;
  }
  else
  {
    cout << "Failure!" << endl;
  }
}

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы