Вы сталкиваетесь с тремя основными проблемами: (1) вы берете имя пользователя у пользователя с fscanf(stdin, "%143[^\t]", a);
, которое будет читать все символы, кроме tab
(включая завершающий '\n'
, генерируемый нажатием Enter ), (2) после открытия файла, введенного пользователем и присвоения возврата от fopen
до data
, у вас нет возможности узнать, действительно ли файл открыт (учитывая завершающий '\n'
, включенный в имя файла,Я подозреваю, что это не удается);и (3) вы фактически никогда не читаете из файлового потока data
(что, вероятно, хорошо, если вы не смогли VALIDATE он был фактически открыт.
Ключ к проверяет каждый критический шаг в вашей программе особенно каждый бит пользовательского ввода . Каждая функция обеспечивает возврат - использует их для проверки , была ли функция выполнена или не выполнена.
Короткий пример добавления проверки (и объявления константы там, где это необходимо - не используйте магические числа в своем коде, кроме случаев, когда это абсолютно необходимо - как в поле scanf
-width модификатор), например
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, define one (or more)
( don't SKIMP on buffer size ) */
int main (void)
{
FILE* data = NULL; /* initialize all variables */
size_t nlines = 0;
char a[MAXC] = "";
printf("Enter a filename: ");
/* VALIDATE EVERY SINGLE BIT OF INPUT */
if (fscanf (stdin, " %1023[^\n]", a) != 1) {
fputs ("user canceled input.\n", stderr);
return 1;
}
/* open/VALIDATE file open for reading */
if ((data = fopen (a, "r")) == NULL) {
perror ("fopen-a");
return 1;
}
printf ("file opened: %s\n\n", a);
/* reuse buffer to read each line */
while (fgets (a, MAXC, data) != NULL)
/* fgets include '\n' in buffer if buffer of sufficient size */
printf ("line[%3zu]: %s", nlines++ + 1, a);
fclose(data);
return 0;
}
Пример входного файла
$ cat dat/file.txt
larry snedden 123 mocking bird lane
sponge bob 321 bikini bottom beach
mary fleece 978 pasture road
hairy whodunit 456 get out of here now lane
Пример Использование / Вывод
$ ./bin/fopen_file_from_user
Enter a filename: dat/file.txt
file opened: dat/file.txt
line[ 1]: larry snedden 123 mocking bird lane
line[ 2]: sponge bob 321 bikini bottom beach
line[ 3]: mary fleece 978 pasture road
line[ 4]: hairy whodunit 456 get out of here now lane