Как выполнить Makefile в Ubuntu для запуска программы C, которая читает из стандартного ввода и выводит на стандартный вывод/stderr

Я работаю над домашним заданием, которое считывает символы из файла input.txt и выводит первое прочитанное слово в output.txt, второе — в error.txt, затем третий снова в output.txt и так далее, пока не будет достигнут конец файла input.txt.

Должен отметить, что все это делается с помощью Ubuntu 18.04

Мне дали пользовательский Makefile, и мне пришлось отредактировать программу на языке C под названием split.c, которая пропускала input.txt через stdin и выводила в stdout/stderr. Я могу написать свою программу на C, и она будет указана ниже, однако я не могу проверить ее правильность, потому что я не понимаю, как запускать make, как правильно настраивать файлы и правильно ли моя программа на C читает и выводит данные. должен.

Я попытался запустить команду make в терминале, но получаю:

make: Не указаны цели и make-файл не найден. Стоп.

Я просмотрел бесчисленное количество статей о Linux, создании «создать файлы» и т. д., но я не знаю, о чем меня спрашивают или что делать, поэтому я стою на месте. Руководство очень ценится!

Пользовательский make-файл выглядит следующим образом и называется Makefile.dat:

CC=gcc
CFLAGS=-Wall
EXEC=split
SRC=$(EXEC).c
TEXT_DIR=test
TEST_INPUT=$(TEST_DIR)/input.txt
OUT=$(TEST_DIR)/stdout.txt
ERR=$(TEST_DIR)/stderr.txt
EXP_OUT=$(TEST_DIR)/output.txt
EXP_ERR=$(TEST_DIR)/error.txt
TEST_REQS=$(TEST_INPUT) $(EXP_OUT) $(EXP_ERR)
DIFF=diff -bBqa

all:  $(EXEC)

$(EXEC): $(SRC)
   $(CC) $(CFLAGS) $(SRC) -o $(EXEC)

.PHONY: test
test: $(TEST_REQS) $(EXEC)
  ./$(EXEC) < $(TEST_INPUT) > $(OUT) 2> $(ERR)
  $(DIFF) $(EXP_OUT) $(OUT)
  $(DIFF) $(EXP_ERR) $(ERR)
  echo TEST PASSED!

.PHONY:  clean
clean:
  $(RM) $(EXEC)

И моя программа на C выглядит так и называется split.c:

#include <stdio.h>

int main(){
   int input;

   // keep getting characters until end-of-file
   while((input = fgetc(stdin)) != EOF){

     // prints to stdout
     printf(stdout, "%d", input);
     if(input = " ")
       printf("\n");    // encounters whitespace so print new line

     // prints to stderr
     printf(stderr, "%d", input);
     if(input = " ")
       printf("\n");    // encounters whitespace so print new line

    }

    return 0;

 }

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

Например:

input.txt содержит текст:

"How do I do this stuff?"

output.txt будет иметь:

 How
 I
 this

error.txt будет иметь:

 do
 do
 stuff?

Я полностью ожидаю, что в моей программе C отсутствует код. Я думал, когда писал программу, печатать на стандартный вывод, затем, если встречаются пробелы, печатать новую строку, затем начинать печать на стандартный вывод и повторять до тех пор, пока не будет достигнут EOF.


person Obsidian    schedule 10.08.2019    source источник
comment
Прежде всего, Makefile должен называться Makefile (без расширения), чтобы make мог его найти.   -  person thisisbenmanley    schedule 11.08.2019
comment
Запустите make -f Makefile.data, затем make -f Makefile.dat test. Или скопируйте/переименуйте Makefile.dat просто в Makefile (или makefile), а затем запустите make и make test (или make all test). Есть много способов добиться нужного результата.   -  person Jonathan Leffler    schedule 11.08.2019
comment
@thisisbenmanley : Вовсе нет: make -f makefile.dat test   -  person Clifford    schedule 11.08.2019
comment
@JonathanLeffler: Поскольку split является зависимостью от цели test, разве недостаточно сделать только цель test?   -  person Clifford    schedule 11.08.2019
comment
@Clifford извините, я перепутал формулировку - Makefile должен называться Makefile (без расширения), чтобы точная команда make автоматически нашла его.   -  person thisisbenmanley    schedule 11.08.2019
comment
@Clifford: да, вы могли бы просто запустить make test с соответствующим присутствующим makefile.   -  person Jonathan Leffler    schedule 11.08.2019
comment
Некоторые обновления... когда я запускаю make, я получаю make: *** No rule to make target 'split.c', needed by 'split'. Stop. Когда я запускаю make -f makefile.dat test, я получаю make: Makefile.dat: No such file or directory. И когда я запускаю make test, я получаю make: *** No rule to make target 'text/input.txt', needed by 'test'. Stop. Есть идеи, что это значит?   -  person Obsidian    schedule 11.08.2019


Ответы (1)


Либо переименуйте Makefile.dat в Makefile, например:

mv Makefile.dat Makefile
make

или запустите make с параметром -f и аргументом вашего Makefile:

make -f Makefile.dat

Убедитесь, что все ваши файлы (split.c, test/input.txt, Makefile) находятся в том же каталоге, что и Makefile, иначе это не сработает.

Обратите внимание на некоторые проблемы с вашим кодом C:

if(input = " ")

неправильно. Во-первых, он присваивает строке с пробелом " " (указатель на char) значение input вместо проверки того, является ли input символом пробела.

Чтобы устранить проблему, используйте это:

if(input == ' ')

в обоих случаях.

person S.S. Anne    schedule 11.08.2019
comment
Это сработало для выполнения make, однако теперь я думаю, что у меня проблема в моем файле split.c. В частности, я получаю эти два предупреждения: split.c:11:11: warning: assignment makes integer from pointer without a cast [-Wint-conversion] в = части моего оператора if. И он также выдает split.c:11:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses] во входной части оператора if. Это относится к обоим операторам If в моей программе. - person Obsidian; 11.08.2019