Самая большая проблема, с которой вы сталкиваетесь - это попытка линейно-ориентированного ввода с помощью функции отформатированный ввод . (и вы используете его неправильно) Использование fscanf
(семейство функций scanf
) полно подводных камней для нового C программиста. Пока вы не знаете, что это такое, избегайте их использования и вместо этого используйте линейно-ориентированные функции ввода fgets()
или POSIX getline()
, которые гарантируют, что вся строка ввода используется каждый раз.
В вашем случае массив lineRead
распадается на указатель при доступе, C11 Standard - 6.3.2.1 Другие операнды - L-значения, массивы и указатели функций (p3) , поэтому вы используете &lineRead
неправильно (в результате параметр для fscanf()
с типом char **
вместо правильного char*
). '&'
не требуется, поскольку lineRead
уже является указателем , поэтому правильное использование будет:
while(fscanf(fin,"%19s",lineRead) == 1){
( примечание: , вы также должны предоставить модификатор field-width для ограничения чтения символов до значения, которое поместится в lineRead
- включая символ с нулевым окончанием . В противном случае вы используете fscanf()
больше не будет безопаснее, чем использование gets()
- который был полностью удален из C11)
Это лишь одна из многих ловушек, ожидающих укуса, используя семейство scanf
.
Вместо этого, используя строково-ориентированную функцию ввода, вы можете сделать:
#include <stdio.h>
#define ROWS 20
#define COLS ROWS /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
char arr[ROWS][COLS];
size_t n = 0;
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* while array not full, read line into array */
while (n < ROWS && fgets (arr[n], COLS, fp)) {
char *p = arr[n]; /* pointer to start of string */
do { /* loop until '\n' found */
if (*p == '\n')
*p = 0; /* overwrite with nul-terminating char */
} while (*p && *++p);
n++; /* increment line counter */
}
if (fp != stdin) /* close file if not stdin */
fclose (fp);
for (size_t i = 0; i < n; i++) /* output stored lines */
printf ("line %2zu : %s\n", i, arr[i]);
}
Используя линейно-ориентированную функцию ввода, '\n'
считывается из ввода и включается в заполненный буфер. Ваша единственная работа - удалить завершающий '\n'
из буфера. Обычно это делается, например, с arr[n][strcspn(arr[n], "\n")] = 0;
, но поскольку вы не можете использовать string.h
, простой l oop будет работать очень хорошо.
Пример использования / Вывод
С вашим входным файлом в dat/cp4int_1.txt
вы передадите имя файла программе в качестве первого аргумента и получите следующий вывод:
$ ./bin/readcp4int_1 dat/cp4int_1.txt
line 0 : ABCDE
line 1 : PQRSTFG
line 2 : acegikmoqsuwyz
line 3 : bdfhjlnprtvx
Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы .