Как перенаправить вывод в файл в C? - PullRequest
1 голос
/ 05 марта 2020

Я пытаюсь, в C:

  1. Считать данные из файла
  2. Манипулировать данными
  3. Записать измененные данные в другой файл

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

gcc -o name name.c 
./name inputFileName.ext > outputFileName.ext

Я не знаком с командой ">". У меня есть пара вопросов:

  1. В сети он говорит, что «>» перенаправляет вывод команды в файл, и я не уверен, что именно означает «вывод команды». Я перенаправляю вывод из моего файла. c в файл outputFileName.ext. Означает ли вывод команды стандартный вывод? Если да, какое ключевое слово C я бы использовал для записи информации в файл outputFileName.ext с именем. c как stdout?
  2. Когда я открываю и читаю свой входной файл, мне нужно получить доступ к файлу, который был передан из командной строки. Считается ли символ «>» еще одним аргументом командной строки? Могу ли я по-прежнему обращаться к inputFileName.ext из main () с помощью выражения «argv [1]»?

Ответы [ 2 ]

3 голосов
/ 05 марта 2020

В сети он говорит, что > перенаправляет вывод команды в файл, и я не уверен, что именно означает «вывод команды».

«вывод команды» относится к stdout (стандартный вывод) поток программы.

Обратите внимание, что некоторые команды оболочки не являются отдельными программами, но на самом деле являются встроенными оболочками , хотя они все еще будут поддерживать перенаправление вывода. В Windows большинство команд оболочки (например, dir и del) являются встроенными, тогда как в Linux / BSD / et c большинство команд оболочки являются отдельными программами (например, ls и mkdir) * 1016. *

Если ваша программа вызывает puts( "foobar" );, то при запуске ./name из Bash в эмуляторе терминала будет отображаться «foobar». Но если вы запустите ./name > file.txt, то текст «foobar» будет записан в file.txt и не будет отображаться в вашем эмуляторе терминала.

Попробуйте выполнить команду ls, например: ls -al > files.txt. Это работает и для Windows (dir /s > files.txt).

Я перенаправляю вывод из моего файла name.c в файл outputFileName.ext. Означает ли вывод команды стандартный вывод?

Да.

Если да, то какое ключевое слово C я бы использовал для записи информации в файл outputFileName.ext из имени. c как стандартный вывод?

Вы этого не делаете. Это функция оболочки / ОС, которая не является частью C.

2 голосов
/ 05 марта 2020

Давайте уточним несколько вещей:

  1. >, < и несколько других символов (которые не имеют отношения к вашему вопросу) являются управляющими операторами для интерпретатора командной строки (он же ракушка). Когда оболочка видит какой-либо из них, она предполагает, что аргументы командной строки для вашей программы завершены. Таким образом, в вашем случае ваша программа будет иметь argc=2 и argv = ["name ", "inputFileName.ext"].
  2. «Перенаправление» означает, что все, что ваша программа будет нормально записывать на экран через stdout (которое по умолчанию выводится при вызове printf() putchar(), puts()) будет записано имя файла, которое следует после >. Ваша пограмма совершенно не знает об этом факте. В вашем коде вы должны просто предполагать, что вы печатаете на экране. Ответственность за выполнение перенаправления несет тот, кто выполняет команду. (Также: «outputFileName.ext» не должен существовать, он будет создан, если он не существует, но перенаправление переопределит все ранее записанное в этом файле, поэтому будьте особенно внимательны, чтобы не перенаправить на. c файл случайно или к вашим результатам вашего предыдущего исполнения, если вам нужны оба )
  3. < (не в вашем вопросе, но тесно связаны) работает наоборот, как вы бы представьте, что программа читает ввод из этого файла, а не с клавиатуры. (очевидно, файл должен существовать сейчас)

Что касается второй части вашего вопроса, вы все еще можете (и должны) получить доступ к имени входного файла через содержимое argv[1]. Вы откроете файл и прочитаете его с помощью некоторых функций C, которые принимают дескриптор файла в качестве аргумента (например, fscanf(), fgets(), getline()).

Наконец, вы убедитесь, что данная команда

./name inputFileName.ext > outputFileName.ext

, а не

./name < inputFileName.ext > outputFileName.ext

?

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

...