为什么我的 shell 程序不打开它在函数“cat”中作为参数接收到的文件?

发布于 2024-12-16 17:54:45 字数 5418 浏览 0 评论 0原文

我在下面包含了代码,很抱歉用这么多代码打扰您。参数解析没问题,我用手表检查了一下。我已经放置了一些 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 printfs 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏花。依旧 2024-12-23 17:54:45

问题是,当您使用 fgets它将换行符包含到字符串中。因此,当您传递文件名时,它会附加一个 \n 字符,该字符是在输入命令时输入的。所以传递的文件名不正确。也许可以在这些线路上乘坐新线路(只是一个指针):

char *filename = strtok(argv[optind], "\n");
if( filename == NULL)
{
   /*What the .... */
   Handle error!
}
FILE * fd = fopen (filename, "r");
printf("am deschis fisierul %s ",argv[optind]);
if (fd == NULL)
{
    printf("FISIER NULL asdasdasdasdasd");
    return 1;
}

希望这会有所帮助!

PS:调试过程
fopen失败时,它会设置errno。要获取确切的错误,请使用 strerror(errno);perror。因此,在 if(fd == NULL) 中添加 perror("fopen"); 显示 fopen :没有这样的文件或目录。接下来将文件名打印为 fprintf(stderr, "\n |%s|\n", argv[optind]); 显示带有换行符的文件名,即

|hello.txt  
|

...然后看到 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):

char *filename = strtok(argv[optind], "\n");
if( filename == NULL)
{
   /*What the .... */
   Handle error!
}
FILE * fd = fopen (filename, "r");
printf("am deschis fisierul %s ",argv[optind]);
if (fd == NULL)
{
    printf("FISIER NULL asdasdasdasdasd");
    return 1;
}

Hope this helps!

PS: Debugging process
When fopen fails it sets the errno. To get exact error use strerror(errno); or perror. So adding perror("fopen"); in if(fd == NULL) showed fopen : No such file or directory. Next printing the file name as fprintf(stderr, "\n |%s|\n", argv[optind]); showed file name with newline character i.e.

|hello.txt  
|

... then saw fgets. Ah! the new line from there

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文