因此,我试图根据用户输入打开文件,但我一直在找回键入的内容。
这就是我所拥有的。
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE* data;
char a[144];
printf("Enter a filename:\n");
fscanf(stdin, "%143[^\t]", a);
data = fopen(a, "r");
printf("%s", a);
fclose(data);
return 0;
}
这是我的文本文件。
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
答案 0 :(得分:3)
您面临三个主要问题:(1)使用fscanf(stdin, "%143[^\t]", a);
从用户那里获取文件名,该文件名将读取不是tab
的所有字符(包括按< kbd> Enter ),(2)打开用户输入的文件并将返回值从'\n'
分配到fopen
之后,您将无法知道文件是否实际打开(给定文件名中包含的结尾data
,我怀疑它失败了); (3)您从未真正从文件流'\n'
中读取文件(这很不错,因为您无法验证实际上是打开的文件。
关键是要验证程序中的每个关键步骤,尤其是用户输入的每一点。每个函数都提供一个回报-使用它们来验证该函数成功还是失败。
添加验证(并在需要的地方声明常量的简短示例-除非绝对需要,否则在代码中不要使用幻数,例如data
字段宽度修饰符),例如
scanf
示例输入文件
#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
答案 1 :(得分:1)
使用fgets()
读取整行输入:
#include <stddef.h> // size_t
#include <stdlib.h> // EXIT_FAILURE
#include <stdio.h> // FILE, fprintf(), fputs(), fgets(), fopen(), fclose()
#include <string.h> // strlen()
enum { MAX_FILENAME_LENGTH = 120 };
int main(void)
{
char filename[MAX_FILENAME_LENGTH + 2]; // + '\n' + '\0'
if (!fgets(filename, sizeof(filename), stdin)) {
fputs("Input error :(\n\n", stderr);
return EXIT_FAILURE;
}
size_t length = strlen(filename); // get rid of the newline at the end:
if (length && filename[length - 1] == '\n')
filename[--length] = '\0';
// When the length of the string is not needed, the above if-statement
// can be replaced as suggested by Jonathan Leffler:
filename[strcspn(filename, "\n")] = '\0'
FILE *input = fopen(filename, "r");
if(!input) {
fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
return EXIT_FAILURE;
}
// do stuff with input
fclose(input);
}
有关如何逐行将整个文件读入内存的信息,请参见this answer。
答案 2 :(得分:0)
min(a, b, c, ...)
读取带有制表符的输入结尾。您可以尝试其他方法。而且您没有从文件流fscanf(stdin, "%143[^\t]", a)
中读取内容。
data
名为 file.txt 的文本文件:
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE* data;
char a[144];
printf("Enter a filename:\n");
fscanf(stdin, "%s", a); //use %s not 143[^t]
data = fopen(a, "r");
//read from the file
char read_from_file[100];
while (!feof(data)) {
fgets(read_from_file, 1024, data);
printf("%s", read_from_file);
}
print("\n")
printf("%s", a);
fclose(data);
return 0;
}
输入:
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
输出:
file.txt