Написать в подкаталог используя freopen

Я пытаюсь записать в файлы внутри подкаталогов, используя freopen:

freopen("output/output-1.txt", "w", stdout);

Я попытался изменить его для вывода в текущий каталог, и он работает. Он завершается без ошибок, когда целевой выходной файл находится в подкаталоге; однако файлы не создаются. Создание необходимого каталога не решает проблему.

void write_to(int subtask, int tc){
    string output = string("testcases/subtask-") + to_string(subtask) + "-tc-" + to_string(tc);
    freopen(output.c_str(), "w", stdout);
}

int main(){
    for(int i = 1; i <= 25; i++){
        write_to(1, i);
        // rest of code to generate and cout test cases
    }
}

У кого-нибудь есть решение этого?

1 ответ

Решение

Прочитайте документацию freopen (3). Вы должны проверить и использовать его результат:

freopen() Функция открывает файл, имя которого является строкой, на которую указывает path и связывает поток, на который указывает поток, с ним. Исходный поток (если он существует) закрыт.

о его возвращаемом значении:

После успешного завершения fopen(), fdopen() а также freopen() вернуть указатель ФАЙЛА. В противном случаеNULL возвращается и errno установлен, чтобы указать на ошибку.

Так что вам нужно как минимум кодировать (если в Linux или какой-либо системе POSIX)

void write_to(int subtask, int tc){
   string output = 
     string("testcases/subtask-") + to_string(subtask) 
      + "-tc-" + to_string(tc);
   FILE*outf = freopen(output.c_str(), "w", stdout);
   if (!outf) {
     perror(output.c_str());
     char pwdbuf[128];
     memset (pwdbuf, 0, sizeof(pwdbuf));
     getcwd(pwdbuf, sizeof(pwdbuf)-1);
     fprintf(stderr, "failure in %s\n", pwdbuf);
     exit(EXIT_FAILURE);
   }
}

(приведенный выше код не решит вашу проблему, но выведет значимое сообщение об ошибке при ошибке; возможно, вы не запускаете свой код в соответствующем текущем каталоге)

Я также рекомендую покончить с for зациклиться main с fflush(stdout) или же fflush(NULL),

Если вы используете Linux или POSIX, вы можете вместо этого работать на уровне дескриптора файла (поэтому кодируйте перенаправление) и использовать open (2) & dup (2) (используя STDOUT_FILENO в качестве второго аргумента dup2).

Если testcases каталог в вашем $HOME (то есть, ~/testcases/ как расширено вашей оболочкой) вы хотели бы

string output =
  string (getenv("HOME")) + "/" 
  + string("testcases/subtask-") + to_string(subtask) 
  + "-tc-" + to_string(tc);
Другие вопросы по тегам