我正在尝试编写允许任何文件名(Makefile,1.txt,abc.txt等)读取屏幕上输出的程序。看来可行,但是只能打印任何文件中最多10行中的一行。
/**
* Get a filename from the command line or print "Usage: p6 <filename>\n" if it
* is not provided and exit. Use fopen(3) to open the file for reading. Then
* use fgets(3) to read at most 10 lines from the file and print them out to the
* console. You may assume that a line of text will not exceed 4096 characters.
* Example input/output:
* ./p6 Makefile
* CC=gcc
*
* PROGS=p1 p2 p3 p4 p5 p6 p7 p8 p9 p10
*
* # Linux defaults:
* CFLAGS=-ggdb -pedantic -Wall
* #CFLAGS=-O4 -Wall
* LDFLAGS=-s
*
* all: $(PROGS)
*/
#include <stdio.h>
int main (int argc, char *argv[])
{
if (argc < 2)
{
printf ("Usage: p6 <filename>\n");
}
FILE *fp;
char str[60];
/* opening file for reading */
fp = fopen ("Makefile", "r"); //In the instruction says Makefile
// When I run check command, I must use
//"/u1/lecture/instructor/.check/text/1.txt" for ".check" file
if (fgets (str, 10, fp) != NULL)
{
puts (str);
}
fclose (fp);
return (0);
}
输出:
> p6:
> -2.5 output of program (p6) is not correct for input '/u1/lecture/instructor/.check/text/1.txt':
> ------ Yours: ------
> man(1) General Commands Manual man(1)
>
> ---- Reference: ----
> man(1) General Commands Manual man(1)
>
> NAME
> man - format and display the on-line manual pages
>
> SYNOPSIS
> man [-acdfFhkKtwW] [--path] [-m system] [-p string] [-C config_file]
> [-M pathlist] [-P pager] [-B browser] [-H htmlpager] [-S section_list]
> [section] name ...
>
> --------------------
对于操作系统,我使用KDE Linux System
提供的CS Instructor
。
答案 0 :(得分:0)
以下建议的代码:
现在,建议的代码:
#include <stdio.h> // fopen(), fclose(), fgets(), fprintf(), printf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
#define MAX_LINE_LEN 4096
#define MAX_LINES 10
int main (int argc, char *argv[])
{
if (argc != 2)
{
fprintf ( stderr, "Usage: %s <filename>\n", argv[0]);
exit( EXIT_FAILURE );
}
char buffer[ MAX_LINE_LEN ];
/* opening file for reading */
FILE *fp = fopen ( argv[1], "r"); //In the instruction says Makefile
if( !fp )
{
perror( "fopen failed" );
exit( EXIT_FAILURE );
}
int i = 0;
while( (i<MAX_LINES) && (fgets ( buffer, sizeof( buffer ), fp)) )
{
printf( "%s", buffer );
i++;
}
fclose (fp);
return (0);
}
没有给出命令行参数的代码运行:
./untitled
Usage: ./untitled <filename>
运行带有有效文件名的代码:
./untitled untitled.c
#include <stdio.h>
#include <stdlib.h>
#define MAX_LINE_LEN 4096
#define MAX_LINES 10
int main (int argc, char *argv[])
{
if (argc != 2)
{
运行的文件名不存在的代码:
./untitled nonexistent.txt
fopen failed: No such file or directory
答案 1 :(得分:0)
通过关注单词Makefile
,您使问题变得比所需的复杂。那是一条红鲱鱼。您刚刚得到的示例之一恰好是打印Makefile的前十行。它不影响编写代码以仅从您在命令行上提供的任何文件名中输出前十行来读取。您可以自由地做同样的事情,并使用Makefile
作为程序的输入,但是除了选择输入文件之外,它与当前的问题无关。
查看您现有的代码,您几乎可以正确地使用基本方法,但是如果使用if (argc < 2)
,则会丢失错误。您不仅要做简单的打印语句,还必须通过将控制权交还给外壳程序(例如return 1;
)来处理错误,以便您的程序不会继续处理试图从永远不会打开的文件中获取数据的尝试
否则,您逻辑上就可以打印行了。只需执行以下操作,即输出在显示行之前显示的行号,然后显示最后显示的行数的总计,例如
#include <stdio.h>
#define MAXC 4096 /* if you need a constant, #define one (or more) */
#define NLINES 10 /* number of lines to read */
int main (int argc, char **argv) {
char line[MAXC]; /* buffer to hold each line */
size_t ndx = 0;
FILE *fp = NULL;
if (argc < 2) { /* validate adequate number of arguments */
fprintf (stderr, "error: insufficient input.\n"
"usage: %s <filename>\n", argv[0]);
return 1;
}
/* open file / validate file open for reading */
if ((fp = fopen (argv[1], "r")) == NULL) {
perror ("fopen(argv[1],\"r\")");
return 1;
}
/* read/output each line while ndx < NLINES */
while (ndx < NLINES && fgets (line, MAXC, fp))
printf ("line[%2zu]: %s", ndx++ + 1, line);
printf ("\ntotal lines read: %zu\n", ndx); /* print total lines */
fclose (fp);
}
编译代码
始终启用编译器警告,并让编译器帮助您修复代码。要启用警告,请在您的-Wall -Wextra
或gcc
编译字符串中添加clang
。 (添加-pedantic
以获得其他一些警告)。对于clang
,您可以使用-Weverything
。对于 VS (在windoze上为cl.exe
),添加/W3
(或使用/Wall
,但您会收到很多无关的与代码无关的警告)。阅读并理解每个警告。他们将确定任何问题以及发生问题的确切路线。 不要接受代码,直到代码干净地编译而没有警告。您只需听编译器试图告诉您的内容,就可以学到很多C语言。
示例输入文件
$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
使用/输出示例
$ ./bin/tenlines dat/captnjack.txt
line[ 1]: This is a tale
line[ 2]: Of Captain Jack Sparrow
line[ 3]: A Pirate So Brave
line[ 4]: On the Seven Seas.
total lines read: 4
文件超过10行:
$ ./bin/tenlines dat/structaddrout.txt
line[ 1]: K1, K2 720 Eucalyptus Ave 105 Inglewood, CA 89030
line[ 2]: O1, O2 7659 Mckinley Ave Los Angeles, CA 90001
line[ 3]: G1, G2 20253 Lorenzana Dr Los Angeles, CA 90005
line[ 4]: N1, N2 20044 Wells Dr Beverly Hills, CA 90210
line[ 5]: H1, H2 5241 Del Moreno Dr Los Angeles, CA 91110
line[ 6]: F1, F2 20225 Lorenzana Dr Los Angeles, CA 91111
line[ 7]: C1, C2 5142 Dumont Pl Azusa, CA 91112
line[ 8]: J1, J2 5135 Quakertown Ave Thousand Oaks, CA 91362
line[ 9]: M1, M2 4819 Quedo Pl Westlake Village, CA 91362
line[10]: E1, E2 4851 Poe Ave Woodland Hills, CA 91364
total lines read: 10
您可以轻松地将Makefile
包含为要读取的文件(只是文本),以了解其价值。
仔细检查一下,如果还有其他问题,请告诉我。