2013-05-18 6 views
-2

У меня возникли трудности с записью функции на C, которая проверяет, существует ли пользовательский файл (через stdin). Например, если программа запущена как ./a.out <myfile.txt, я хочу, чтобы она вернула false, если этот файл не существует. Я могу сделать это путем передачи файла в качестве аргумента (т.е. ./a.out myfile.txt) с помощью fopen(), но не знаю, как это сделать с помощью «стандартного ввода» (т.е. ./a.out <myfile.txt)Проверка наличия файла через stdin (C)

Ok уточнить:

Чем больше программы должен взять содержимое текстового файла и выполнить на нем действия. Программа должна запускаться в командной строке как ./a.out arg1 arg2 <myfile.txt. Если пользователь запускал программу как ./a.out arg1 arg2 или ./a.out (т. Е. Не указывая файл для выполнения действий), я хочу предложить пользователю включить файл (используя stdin <, не переданный в качестве аргумента).

+3

Если файл не существует, оболочка не запускает вашу программу. – Barmar

+0

@Barmar да, но это часть более крупной программы, которую я пишу, и я хочу напечатать 'введите действительный файл', если он не существует. – Martin

+1

Перед попыткой запустить программу необходимо проверить, существует ли файл. – Barmar

ответ

3

STDIN не может приходить из файла вообще. Даже если это так, когда пользователь вводит «< myfile.txt» в командной строке, оболочка проглатывает эту часть команды и никогда не передает ее в программу. Что касается программы, это анонимный поток байтов, который может быть из файла, устройства, терминала, трубы или чего-то еще. Можно запросить, какой из них у вас есть, но даже если вы знаете, что это файл, вы не получите имя файла, указанного в командной строке, только inode.

+0

«создает канал для подачи в программу» - ну, нет, оболочка не создает канал при задании «<». –

+0

«Что касается программы» - Ум, найдите 'stat' и' ESPIPE'. Обычно программы могут сообщать, какие вещи они читают, и не все операции являются законными для всех типов ввода. –

+0

То, что вы знаете, не имеет значения, поскольку вы явно не знаете, как работает оболочка. * Нет * UNIX shell открывает канал для «<» ... только для «|». Я сделал разработку внутри оболочки Mashey, оболочки Bourne и csh, и я хорошо знаком с тем, как они работают. –

2

Поскольку оболочка отвечает за открытие файла для перенаправления, он откажется выполнить команду, если файл не открывается.

+0

См. Мое обновление выше. – Martin

+2

Ваше обновление не имеет смысла. Либо данные перенаправляются, либо нет. Ваша программа должна решить, следует ли принимать входные данные из stdin. –

1

OS предотвращает вызов вашей программы, поскольку она может предоставить действительный номер stdin, если myfile.txt не существует. Программа не запускается, поэтому вы не можете сигнализировать, что файл отсутствует, и эта диагностика выполняется на уровне ОС.

2

Перенаправление ввода - это что-то сделанное раковиной , не ваша программа. Он просто прикрепляет файл к стандартным вводам.

Таким образом, если попытаться перенаправить ввод из несуществующего файла, оболочки должен горько жаловаться и даже не запустить ваша программа, как показано в следующем стенограмме:

pax> echo hello >qq.in 

pax> cat <qq.in 
hello 

pax> cat <nosuchfile.txt 
bash: nosuchfile.txt: No such file or directory 

В любом случае, ваша программа вообще не знать где вход приходит, так как вы можете сделать что-то вроде:

echo hello | cat 

, в котором участвует нет.


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

Или, вы можете обнаружить существование файла перед тем выполнение вашей программы, что-то вроде следующего bash сегмента:

fspec=/tmp/infile 
if [[ -f ${fspec} ]] ; then 
    my_prog <${fspec} 
else 
    echo What the ... 
fi 
+0

См. Мое обновление выше. – Martin

+0

@ InvisibleH763 Пожалуйста, просмотрите ответы, которые вы не читаете, или не читаете внимательно. –

0

Если пользователь запускал программу как ./a.out arg1 arg2 или ./a.out (то есть не указывая файл для выполнения действий), я хочу предложить пользователю включить файл (используя stdin <, не переданный в качестве аргумента).

Вы можете использовать функции, специфичные для ОС, для проверки того, является ли stdin терминалом. Проверка того, является ли это файлом очень плохая идея, потому что очень полезно подключаться к stdin ... на самом деле, это основная причина, по которой в первую очередь стоит stdin. Если вы хотите читать только файл, а не терминал или трубу, тогда вы должны взять имя файла в качестве обязательного аргумента и не читать из оригинального stdin (вы все равно можете читать из stdin с помощью freopen). Если вы настаиваете на том, что вы не хотите этого делать, я буду настаивать на том, что вы хотите сделать это неправильно.

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