为什么我的 shell 程序不打开它在函数“cat”中作为参数接收到的文件?
我在下面包含了代码,很抱歉用这么多代码打扰您。参数解析没问题,我用手表检查了一下。我已经放置了一些 printf
来检查问题可能出在哪里,但它似乎没有打开 cat
作为参数接收的文件。它从 shell 中调用为“cat -b file
”
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define TRUE 0
#define FALSE 1
void yes(int argc, char *argv[]);
int cat(int argc, char *argv[]);
//#include "cat.h"
//#include "yes.h"
//#include"tee.h"
char buf[50],c[10], *p2,*p, *pch;
int count;
char *matrix[20];
void yes(int argc, char *argv[])
{
int i;
// if (argc >= 2 && *argv[1] == '-')
// {
//printf("ERROR!");
//}
//if (argc == 1)
// {
while (1)
if (puts("y") == EOF)
{
perror("yes");
exit(FALSE);
}
// }
while (1)
for (i = 1; i < argc; i++)
if (fputs(argv[i], stdout) == EOF || putchar(i == argc - 1 ? '\n' : ' ') == EOF)
{
perror("yes");
exit(FALSE);
}
//exit(TRUE);
}
int main(int argc, char *argv[])
{
//p=(char *)malloc(sizeof(char)*50);
do
{
fprintf (stderr, "$ ");
fgets (buf,50,stdin);
p=buf;
fprintf (stderr, "Comanda primita de la tastatura: ");
fputs (buf, stderr);
int i=0,j=0;
//strcpy(p,buf);
strcpy(c,"\0");
while (buf[i] == ' ')
{
i++;
p++;
}
if (buf[i] == '#')
fprintf (stderr, "Nici o comanda, ci e un comentariu!\n");
else
{
j=0;
while (buf[i] != ' ' && buf[i] != '\n')
{
i++;
j++;
}
strncpy (c,p,j);
fprintf (stderr, "%s\n",c);
if (strcmp (c,"yes") == 0)
{
p2 = p+j+1;
pch = strtok (p2," ");
count = 0;
while (pch != NULL)
{
//printf ("%s\n",pch);
matrix[count] = strdup(pch);
pch = strtok (NULL, " ");
count++;
}
yes(count, matrix);
fprintf (stderr, "Aici se va executa comanda yes\n");
}
else if (strcmp (c,"cat") == 0)
{
p2 = p+j+1;
pch = strtok (p2," ");
count = 0;
while (pch != NULL)
{
//printf ("%s\n",pch);
matrix[count] = strdup(pch);
pch = strtok (NULL, " ");
count++;
}
cat(count,matrix);
fprintf (stderr, "Aici se va executa comanda cat \n");
}
else if (strcmp (c,"tee") == 0)
{
//tee();
fprintf(stderr, "Aici se va executa comanda tee\n");
}
fprintf (stderr, "Aici se va executa comanda basename\n");
strcpy(buf,"\0");
}
}
while (strcmp(c, "exit") != 0);
fprintf (stderr, "Terminat corect!\n");
return 0;
}
int cat(int argc, char *argv[])
{
int c ;
opterr = 0 ;
optind = 0 ;
char number = 0;
char squeeze = 0;
char marker = 0;
fprintf(stderr,"SALUT< SUNT IN FUNCTIZE>\n");
while ((c = getopt (argc, argv, "bnsE")) != -1)
switch (c)
{
case 'b' :
number = 1;
break;
case 'n' :
number = 2;
break;
case 'm' :
marker = 1;
break;
case 's' :
squeeze = 1;
break;
case 'E' :
marker = 1;
break;
}
if (optind + 1 != argc)
{
fprintf (stderr, "\tWrong arguments!\n") ;
return -1 ;
}
FILE * fd = fopen (argv[optind], "r");
printf("am deschis fisierul %s ",argv[optind]);
if (fd == NULL)
{
printf("FISIER NULL asdasdasdasdasd");
return 1;
}
char line[1025];
int line_count = 1;
while (!feof(fd))
{
fgets(line, 1025, fd);
printf("sunt in while :> %s",line);
int len = strlen(line);
if (line[len - 1] == '\n')
{
if(len - 2 >= 0)
{
if(line[len - 2] == '\r')
{
line[len - 2] = '\0';
len -= 2;
}
else
{
line[len - 1] = '\0';
len -= 1;
}
}
else
{
line[len - 1] = '\0';
len -= 1;
}
}
if (squeeze == 1 && len == 0)
continue;
if (number == 1)
{
fprintf (stdout, "%4d ", line_count);
line_count++;
}
else if (number == 2)
{
if (len > 0)
{
fprintf (stdout, "%4d ", line_count);
line_count++;
}
else
fprintf (stdout, " ");
}
fprintf(stdout, "%s", line);
if (marker == 1)
fprintf(stdout, "$");
fprintf(stdout, "\n");
}
fclose (fd);
return 0 ;
}
I included the code below, sorry to bother you with so much code. Argument parsing is ok, i checked it out with watches. I've put some printf
s to check out where the problem may be and it seems that it doesn't open the file cat
receives as argument. It is called from a shell as "cat -b file
"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define TRUE 0
#define FALSE 1
void yes(int argc, char *argv[]);
int cat(int argc, char *argv[]);
//#include "cat.h"
//#include "yes.h"
//#include"tee.h"
char buf[50],c[10], *p2,*p, *pch;
int count;
char *matrix[20];
void yes(int argc, char *argv[])
{
int i;
// if (argc >= 2 && *argv[1] == '-')
// {
//printf("ERROR!");
//}
//if (argc == 1)
// {
while (1)
if (puts("y") == EOF)
{
perror("yes");
exit(FALSE);
}
// }
while (1)
for (i = 1; i < argc; i++)
if (fputs(argv[i], stdout) == EOF || putchar(i == argc - 1 ? '\n' : ' ') == EOF)
{
perror("yes");
exit(FALSE);
}
//exit(TRUE);
}
int main(int argc, char *argv[])
{
//p=(char *)malloc(sizeof(char)*50);
do
{
fprintf (stderr, "$ ");
fgets (buf,50,stdin);
p=buf;
fprintf (stderr, "Comanda primita de la tastatura: ");
fputs (buf, stderr);
int i=0,j=0;
//strcpy(p,buf);
strcpy(c,"\0");
while (buf[i] == ' ')
{
i++;
p++;
}
if (buf[i] == '#')
fprintf (stderr, "Nici o comanda, ci e un comentariu!\n");
else
{
j=0;
while (buf[i] != ' ' && buf[i] != '\n')
{
i++;
j++;
}
strncpy (c,p,j);
fprintf (stderr, "%s\n",c);
if (strcmp (c,"yes") == 0)
{
p2 = p+j+1;
pch = strtok (p2," ");
count = 0;
while (pch != NULL)
{
//printf ("%s\n",pch);
matrix[count] = strdup(pch);
pch = strtok (NULL, " ");
count++;
}
yes(count, matrix);
fprintf (stderr, "Aici se va executa comanda yes\n");
}
else if (strcmp (c,"cat") == 0)
{
p2 = p+j+1;
pch = strtok (p2," ");
count = 0;
while (pch != NULL)
{
//printf ("%s\n",pch);
matrix[count] = strdup(pch);
pch = strtok (NULL, " ");
count++;
}
cat(count,matrix);
fprintf (stderr, "Aici se va executa comanda cat \n");
}
else if (strcmp (c,"tee") == 0)
{
//tee();
fprintf(stderr, "Aici se va executa comanda tee\n");
}
fprintf (stderr, "Aici se va executa comanda basename\n");
strcpy(buf,"\0");
}
}
while (strcmp(c, "exit") != 0);
fprintf (stderr, "Terminat corect!\n");
return 0;
}
int cat(int argc, char *argv[])
{
int c ;
opterr = 0 ;
optind = 0 ;
char number = 0;
char squeeze = 0;
char marker = 0;
fprintf(stderr,"SALUT< SUNT IN FUNCTIZE>\n");
while ((c = getopt (argc, argv, "bnsE")) != -1)
switch (c)
{
case 'b' :
number = 1;
break;
case 'n' :
number = 2;
break;
case 'm' :
marker = 1;
break;
case 's' :
squeeze = 1;
break;
case 'E' :
marker = 1;
break;
}
if (optind + 1 != argc)
{
fprintf (stderr, "\tWrong arguments!\n") ;
return -1 ;
}
FILE * fd = fopen (argv[optind], "r");
printf("am deschis fisierul %s ",argv[optind]);
if (fd == NULL)
{
printf("FISIER NULL asdasdasdasdasd");
return 1;
}
char line[1025];
int line_count = 1;
while (!feof(fd))
{
fgets(line, 1025, fd);
printf("sunt in while :> %s",line);
int len = strlen(line);
if (line[len - 1] == '\n')
{
if(len - 2 >= 0)
{
if(line[len - 2] == '\r')
{
line[len - 2] = '\0';
len -= 2;
}
else
{
line[len - 1] = '\0';
len -= 1;
}
}
else
{
line[len - 1] = '\0';
len -= 1;
}
}
if (squeeze == 1 && len == 0)
continue;
if (number == 1)
{
fprintf (stdout, "%4d ", line_count);
line_count++;
}
else if (number == 2)
{
if (len > 0)
{
fprintf (stdout, "%4d ", line_count);
line_count++;
}
else
fprintf (stdout, " ");
}
fprintf(stdout, "%s", line);
if (marker == 1)
fprintf(stdout, "$");
fprintf(stdout, "\n");
}
fclose (fd);
return 0 ;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是,当您使用
fgets
它将换行符包含到字符串中。因此,当您传递文件名时,它会附加一个\n
字符,该字符是在输入命令时输入的。所以传递的文件名不正确。也许可以在这些线路上乘坐新线路(只是一个指针):希望这会有所帮助!
PS:调试过程
当
fopen
失败时,它会设置errno
。要获取确切的错误,请使用strerror(errno);
或perror
。因此,在if(fd == NULL)
中添加perror("fopen");
显示fopen :没有这样的文件或目录
。接下来将文件名打印为fprintf(stderr, "\n |%s|\n", argv[optind]);
显示带有换行符的文件名,即...然后看到
fgets
。啊!从那里开始的新线路The problem is that when you are using
fgets
it includes the newline into the string. Thus when you are passing the file name, it is appended with a\n
character which was enter when entering the command. So the file name passed is incorrect. Get ride of the new line maybe on these lines (just a pointer):Hope this helps!
PS: Debugging process
When
fopen
fails it sets theerrno
. To get exact error usestrerror(errno);
orperror
. So addingperror("fopen");
inif(fd == NULL)
showedfopen : No such file or directory
. Next printing the file name asfprintf(stderr, "\n |%s|\n", argv[optind]);
showed file name with newline character i.e.... then saw
fgets
. Ah! the new line from there