我有一个C文件,它读取用户输入并根据各种命令进行打印。
例如,如果我执行./cat -n filename
然后它在每行打印数字
如果我执行./cat -e filename
然后它在每行打印$
到目前为止它的工作正常,但当我同时执行两个命令,如./cat -n -e filename时,它会打印一个文件两次,因为我在两种情况下都保留了printf语句。但是我想只打印一次输出。
这是我的代码
#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int flag = 0;
char *cvalue = NULL;
int index;
int c;
char buffer[256];
int linecount=1;
opterr = 0;
FILE *file ;
while ((c = getopt (argc, argv, "net")) != -1)
switch (c)
{
printf("string %c",c);
case 'n':
printf("optind %d",optind);
for (index = optind; index < argc; index++)
{
FILE *file;
file = fopen(argv[index], "r" );
// printf("command %s",argv[1]);
/* fopen returns 0, the NULL pointer, on failure */
if(argc<=2)
{
while (fgets(buffer, sizeof(buffer), stdin))
{
//it will print the user input with number
printf("\t %d %s", linecount, buffer);
//it will increase the variable by 1
linecount++;
}
printf("\n");
linecount=1;
}
if ( file == 0 )
{
}
else
{
while (fgets(buffer, sizeof(buffer), file))
{
//it will print the user input with number
printf("\t %d %s", linecount, buffer);
//it will increase the variable by 1
linecount++;
}
printf("\n");
linecount=1;
}
}
break;
case 'e':
for (index = optind; index < argc; index++)
{
int x;
FILE *file;
file = fopen(argv[index], "r" );
// printf("command %s",argv[1]);
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
}
else
{
while ((x = fgetc(file)) != EOF)
{
//it will print the user input
if(x =='\n')
{
//It will add '$' at the end of each line
printf("$");
}
else if(x=='\r')
{
printf("$^M");
}
//it will print each line
printf("%c",x );
}
}
}
break;
case 't':
for (index = optind; index < argc; index++)
{
FILE *file;
file = fopen(argv[index], "r" );
// printf("command %s",argv[1]);
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
}
else
{
while (fgets(buffer, sizeof(buffer), file))
{
char *str =buffer;
while(*str){
switch(*str){
// case '\v': printf("\\v");break;
// case '\n': printf("\\n"); break;
case '\t': printf("^I"); break;
default: putchar(*str);break;
}
str++;
}
// printf("%s \n", buffer);
}
}
}
break;
default:
abort ();
}
//printf ("aflag = %d, bflag = %d, cvalue = %s\n",
// aflag, bflag, optarg);
// for (index = optind; index < argc; index++)
//printf ("Non-option argument %s\n", argv[index]);
getchar();
return 0;
}
当前输出:
1 #include<stdio.h>
2
3
4
5
6
7
8 int main()
9 {
10 printf("hello");
11
12
13
14 getchar();
15 return 0;
16 }
#include<stdio.h>$
$
$
$
$
$
$
int main()$
{$
printf("hello");$
$
$
$
getchar();$
return 0;$
}$
必需输出:
1 #include<stdio.h>$
2 $
3 $
4 $
5 $
6 $
7 $
8 int main()$
9 {$
10 printf("hello");$
11 $
12 $
13 $
14 getchar();$
15 return 0;$
16 }$
答案 0 :(得分:2)
您应该将getopt循环与业务逻辑分开。
以下是您可以执行此操作的示例:
int main(int argc, char *argv[])
{
int flag = 0;
char *cvalue = NULL;
int index;
int c;
char buffer[256];
int linecount=1;
opterr = 0;
FILE *file;
int opt_n = 0, opt_e = 0, opt_t = 0;
while ((c = getopt (argc, argv, "net")) != -1) {
switch (c)
{
printf("string %c",c);
case 'n':
opt_n = 1;
break;
case 'e':
opt_e = 1;
break;
case 't':
opt_t = 1;
break;
}
}
for (index = optind; index < argc; index++) {
file = fopen(argv[index], "r" );
if (file == NULL) {
/* add code to print error message and exit */
}
while (fgets(buffer, sizeof(buffer), file))
{
if (opt_n) {
// print line number
printf("%4d ", linecount);
}
if (opt_t) {
print_t(buffer); /* you need to create this function */
} else {
printf("%s", buffer);
}
if (opt_e) {
printf("$");
}
linecount++;
printf("\n", linecount);
}
fclose(file);
}
getchar();
return 0;
}
答案 1 :(得分:2)
正如Paul R评论的那样,首先要检查是否存在这样的标志:
bool eflag = false;
bool nflag = false;
/* ... */
while ((c = getopt (argc, argv, "ent")) != -1) {
switch (c) {
case 'n':
nflag = true;
break;
case 'e':
eflag = true;
break;
/* ... */
default:
fprintf(stderr, "unknown option %c\n", c);
}
}
然后你可以处理输入文件,并对你检测到的标志作出反应:
for (index = optind; index < argc; index++) {
/* cut file opening stuff for brevity */
while (fgets(buffer, sizeof(buffer), file) {
if (nflag) {
printf("%d", linecount);
}
/* the other flags need char-wise processing */
for (cvalue = *buffer; *cvalue != '\0'; cvalue++) {
switch (*cvalue) {
case '\n':
if (eflag) {
printf("$");
}
printf("\n");
break;
/* check other characters */
}
}
}
}
这样,您可以轻松添加其他标志,或更改您对标志的反应方式。
而且,更重要的是,您只有一次出现文件处理代码。想象一下,你的文件处理有一个错误,在旧的代码中你必须修改它的每一次出现,并且在修复它时可能会忘记一些错误的实例。这样,您只需要修复一次,所有情况都是正确的。
最后,它只输出一次处理过的文件。