Поэтому следующая программа не знает, сколько файлов получит, поэтому я использовал вектор указателей для хранения указателей на все файлы. В любом случае пользователь должен ввести со стандартного ввода вектор строк и остановку чтения при вводе /exit
, но перед этим также должна быть выполнена команда ./program file1 file2 ... fileN
. После fileN
программа принимает следующие строки в качестве аргументов командной строки, что я не планировал.
Первый:
./program file1.txt file2.jpg file3.in
и стандартный ввод:
sort
alg
di
pi
food
/exit
Взгляни:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{ char c;
//Allocate memory for the file array based on the number of command line arguments
FILE **f = malloc((argc-1)*sizeof(FILE*)); //invalid conversion from ‘void*’ to ‘FILE**’ {aka //‘_IO_FILE**’} [-fpermissive]
int i;
for (i=1; i<argc; i++) {
printf("%s\n", argv[i]);
f[i - 1] = fopen(argv[i],"r");
}
while((c= getchar()) != '\n' && c != EOF); //invalid conversion from ‘void*’ to ‘char**’ //[-fpermissive]
char **text=malloc(300*sizeof(char*));
for (i=0; i<=30; i++) //invalid conversion from ‘void*’ to ‘char**’ [-fpermissive]
text[i]=malloc(300*sizeof(char));
char s[30];
int N=0;
int ok=0;
while (ok==0)
{
fgets(s,30,stdin);
strcpy(text[N], s);
if (strncmp(s,"/exit",5)==0)
ok=1;
N++;
}
for (i=0; i<N; i++)
printf("%s\n", text[i]);
// free memory after usage
free(f);
for(int i=0;i<30;i++)
free(text[i]);
free(text);
return 0;
}
Когда я нажимаю кнопку запуска, выдает странные ошибки, например:
invalid conversion from ‘void*’ to ‘char**’ [-fpermissive]
или
invalid conversion from ‘void*’ to ‘FILE**’ {aka ‘_IO_FILE**’} [-fpermissive]
(см. код).
Я изменил malloc на char text[300][300]
, но все еще не мог прочитать текст со стандартного ввода.
Он должен печатать вектор строк, но ничего не делает, если я передаю аргументы командной строки, а если я нажимаю «Выполнить», он просто выдает ошибки, указанные выше.
Программа предназначена для простого чтения имен файлов в качестве аргументов командной строки (минимальное количество аргументов 1 и максимальное 9), а затем вектора строк из stdin и печати вектора строк в stdout.
(Файлы, переданные в качестве аргументов командной строки, потребуются позже для поиска совпадающих строк со строками из вектора строк. Я не писал код для этого, так как вектор строк не читается должным образом)
Можете ли вы помочь мне прочитать аргументы командной строки и вектор строк одновременно?
char c;
--> int c;
чтобы обнаружить EOF
Пожалуйста, отредактируйте свой вопрос и добавьте описание того, что программа должна делать с входными данными из stdin
и файлами, указанными в командной строке. Зачем вам (думаю, вам) нужен массив входных строк и массив FILE
указателей?
@tadman Только C, а не C++
@Bodo Сначала я хочу распечатать ввод со стандартного ввода (который хранится в тексте [][]), чтобы увидеть, работает ли чтение. Я должен использовать массив указателей FILE, потому что количество файлов может быть от 1 до 9 (пользователь может ввести 2 файла или только 3 файла и т. д.). У вас есть другое предложение?
Вы не объясняете цель своей программы. Совершенно непонятно, как связаны имена файлов аргументов командной строки и список строк.
Без более подробной информации трудно предложить решение. Я бы, вероятно, сначала прочитал STDIN, а затем перебрал аргументы командной строки и открыл входные файлы один за другим.
Появится сообщение об ошибке invalid conversion from ‘void*’ to ‘char**’
если вы компилируете исходный код как c++
. Приведите результат как
text = (char **)malloc( .. )
чтобы этого избежать.
Если вы компилируете код как c
, такой ошибки не возникнет.
Исходя из ваших требований, не могли бы вы попробовать следующее:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EXIT_CODE "/exit"
int main(int argc, char *argv[])
{
char **text = NULL; // array of strings
char line[BUFSIZ]; // line buffer while reading from stdin
char *p; // temporal pointer on the input line
int n = 0; // line counter of stdin
int i; // general index
FILE **fp; // array of file pointers
if (NULL == (fp = malloc((argc - 1) * sizeof(FILE *)))) {
perror("malloc");
return EXIT_FAILURE;
}
for (i = 1; i < argc; i++) { // open files in the arguments
printf("%s\n", argv[i]);
if (NULL == (fp[i - 1] = fopen(argv[i], "rb"))) {
perror(argv[i]);
return EXIT_FAILURE;
}
}
while (fgets(line, BUFSIZ, stdin)) {
if ((p = strrchr(line, '\n'))) *p = '\0'; // remove trailing newline, if any
if ((p = strrchr(line, '\r'))) *p = '\0'; // remove trailing cr character, if any
if (NULL == (text = realloc(text, (n + 1) * sizeof(char **)))) {
perror("realloc");
return EXIT_FAILURE;
}
if (NULL == (text[n] = malloc(strlen(line) + 1))) {
// allocate memory for the input line
perror("malloc");
return EXIT_FAILURE;
}
strcpy(text[n], line);
n++; // increment the line counter
if (strncmp(line, EXIT_CODE, strlen(EXIT_CODE)) == 0) break;
}
// show the input from stdin
for (i = 0; i < n; i++)
printf("%s\n", text[i]);
/*
* do your processings of the input files here
*/
// free memory after usage
for (i = 1; i < argc; i++)
fclose(fp[i - 1]);
free(fp);
for (i = 0; i < n; i++)
free(text[i]);
free(text);
return EXIT_SUCCESS;
}
для этих условий: if (NULL == (fp = malloc((argc - 1) * sizeof(FILE *)))) это дает следующую ошибку: значение типа "void *" не может быть присвоено объекту типа "FILE **", а для if (NULL == (text = realloc(text, (n + 1) * sizeof(char **))))) выдает ошибку: значение типа "void *" не может быть присваивается объекту типа "char *"
Итак, очевидно, после замены if (NULL == (fp = malloc((argc - 1) * sizeof(FILE *))))
на if (NULL == (fp = (FILE **)malloc((argc - 1) * sizeof(FILE *))))
и аналогично для двух других условных выражений, упомянутых в моем предыдущем комментарии (добавление (char*)
и (char **)
перед malloc
и realloc
), это работает отлично. @tshiono большое спасибо, вы даже не представляете, как я ценю вашу помощь!
Вы компилируете как C или непреднамеренно как C++?