Ищем строку символов, скопированных в буфер - PullRequest
1 голос
/ 15 октября 2011

У меня есть задание, которое попросило меня скопировать файл с использованием буферизованного ввода-вывода.Он имеет несколько требований:

  1. Взять один параметр и дополнительный второй
  2. Открыть первый параметр для чтения
  3. Открыть второй для записи
  4. Если второго параметра нет, создайте новый файл с именем prog1.out
  5. Используйте размер буфера 20 байт
  6. При копировании файла выведите любой буфер, начинающийся с символов "rwxr"
  7. закройте все открытые файлы перед выходом.

У меня проблема с номером шесть, я оглянулся и не могу понять это.Я пробовал memchr, но я не думаю, что я на правильном пути.Если кто-нибудь может помочь подтолкнуть меня в правильном направлении, я буду благодарен.

Это мой код:

# include <stdlib.h>
# include <stdio.h>

int main(int argc, char *argv[])
{

    FILE *readfile, *writefile;
    char buffer[1024];
    int fileSize;
    int readResult;
    int writeResult;

    // making sure arguments exist
    if (argc < 2|| argc > 3){
            printf("This program takes either 1 or 2 arguments.\n");
            exit(1);
    }

    //Opening file for reading
    readfile = fopen(argv[1], "r");
    if (!readfile) {
            printf("Unable to open file %s.\n", argv[1]);
            exit(1);
    }

    //finding the file size
    fseek (readfile, 0, SEEK_END);
    fileSize = ftell (readfile);
    fseek (readfile, 0, SEEK_SET);

    // read the file
    readResult = fread(buffer, 20, fileSize/20, readfile);
    if (readResult == 0) {
            printf("A read error occured.\n");
            exit(1);
    }

    //check to see if there is a second parameter (argument)
    if (argc == 3) {
            writefile = fopen(argv[2], "w");

            if (!writefile) {
                    printf("Unable to open file  %s.\n", argv[2]);
                    exit(1);
            }

            writeResult = fwrite(buffer, 20, fileSize/20, writefile);
            if (writeResult != readResult) {
                    printf("A write error occured.\n");
                    exit(1);
            }
            printf("File %s successfully copied to %s.\n", argv[1], argv[2]);
    }
    else {
            writefile = fopen("program1.out", "w");

            if (!writefile) {
                    printf("Unable to open file program1.out\n");
                    exit(1);
            }

            writeResult = fwrite(buffer, 20, fileSize/20, writefile);
            if (writeResult != readResult) {
                    printf("A write error occured.\n");
                    exit(1);
            }
            printf("File %s successfully copied to %s.\n", argv[1], "program1.out
    }
    fclose(readfile);
    fclose(writefile);
    exit(0);
}

Ответы [ 2 ]

0 голосов
/ 15 октября 2011

Сначала я отвечу на вопрос, который вы на самом деле задали: memcmp - хороший способ сравнить два буфера. Некоторые предостережения:

  • Вы также должны убедиться, что размер буфера не меньше размера целевой строки
  • memcmp возвращает 0, если два буфера совпадают, что может быть нелогичным.

Так, например, если вы хотите увидеть, равен ли буфер строке "rwxw", вы можете написать

if (readresult >= strlen("rwxw") && !memcmp(buffer, "rwxw", strlen("rwxw"))) {
    // buffer match occurred!
}

Лично я бы использовал символ "#define" или const, чтобы гарантировать, что три места, где появляется эта строка, на самом деле - одна и та же строка. Например:

#define MATCH_STRING "rwxw"

if (readresult >= strlen(MATCH_STRING) && !memcmp(buffer, MATCH_STRING, strlen(MATCH_STRING))) {
    // buffer match occurred!
}

Однако есть несколько других проблем с вашим кодом. Во-первых, вам нужен цикл, который непрерывно читает из входного файла и записывает из выходного файла, пока ввод не будет исчерпан. Например, по линии

while (true) {
    readResult = fread(buffer, 20, 1, readfile);

    if (readResult == 0) {
        // end of file
        break;
    }

    // put your check for the "rwxr" string here!

    writeResult = fwrite(buffer, readResult, 1, writefile);

    if (writeResult != readREsult) {
        printf("error\n");
    }
}

Наконец, у вас есть то, что можно назвать «стилистической» ошибкой. В вашей программе есть два случая: указанное имя файла и имя файла по умолчанию. Эти два случая имеют много общего кода, но вы сделали вырезку и вставку. Это делает код более трудным для понимания и более подверженным ошибкам, если он будет изменен в будущем. Если вы вырезаете и вставляете код, вы делаете что-то не так! Рассмотрим вместо этого что-то вроде этого, которое максимизирует пути общего кода:

char *outFileName;

if (argc == 3) {
     outFileName = argv[2];
} else {
     outFileName = "prog1.out";
}  

writefile = fopen(outFileName, "w"); 

if (!writefile) {
   printf("Unable to open file %s.\n", writeFileName);
   exit(1);
}
0 голосов
/ 15 октября 2011

Есть наивный путь:

if(buffer[0] == 'r' && buffer[1] == 'w' 
   && buffer[2] == 'x' && buffer[3] == 'r') {
   //do something
}

Но взгляните на strncmp (), который вы можете использовать для сравнения частей строки.

  • не забудьте сначала проверить, прочитали ли вы по крайней мере 4 символа в буфер. например если файл имеет длину 21 байт, ваш 2. fread может прочитать только 1 символ, и вы не должны сравнивать его с другими 3 символами в буфере.

  • Если вы распечатываете буфер, например, с помощью printf или put или любая другая функция, которая ожидает строку, буфер должен заканчиваться байтом '\ 0', в противном случае строковые функции не знают, когда остановиться.

...