Почему моя программа-оболочка не открывает файл, полученный в качестве аргумента в функции "cat" - PullRequest
0 голосов
/ 17 ноября 2011

Я включил код ниже, извините, что беспокою вас так много кода.Разбор аргументов в порядке, я проверил это с помощью часов.Я положил printf s, чтобы проверить, где может быть проблема, и кажется, что он не открывает файл, который cat получает в качестве аргумента.Он вызывается из оболочки как "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 ;
}

1 Ответ

3 голосов
/ 17 ноября 2011

Проблема в том, что когда вы используете 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. Таким образом, добавление perror("fopen"); в if(fd == NULL) показало fopen : No such file or directory. Затем напечатайте имя файла как fprintf(stderr, "\n |%s|\n", argv[optind]);, указав имя файла с символом новой строки, т.е.

|hello.txt  
|

... потом увидел fgets. Ах! новая строка оттуда

...