2016-12-08 5 views
0

Я пытаюсь написать в файлы в подкаталогах с помощью 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 
    } 
} 

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

+3

путь спецификации относительно текущего каталога исполнения не в директории исполняемого находится в. –

+1

Существует ли каталог 'output'? –

+0

@MichaelWalz Да, он уже существует –

ответ

1

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

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

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

После успешного завершения fopen(), fdopen() и freopen() возвращает указатель на FILE. В противном случае возвращается, 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); 
+0

Спасибо, это решило проблему. Ошибка: Permission Denied - выполнение с правами root разрешало создавать файлы в подкаталогах. –

+1

Вы никогда не должны запускать как root программу, которую вы написали, если только вы не уверены, что у вас нет дыры в безопасности. –

Смежные вопросы