簡體   English   中英

C unistd.h write()命令寫入額外字符

[英]C unistd.h write() command write extra character

我一直在嘗試通過使用系統調用(read(),write(),open(),close())在unix / linux中對cp命令進行c編程實現。

但是當我通過終端運行程序時,將我的程序源代碼復制到相同的目錄(更改名稱)(源代碼大約300行)

當我打開該輸出文件時,它的字符比原始文件更多。

多余的線與200ish線相同。 它來自哪里?

這是編譯時的屏幕截圖

argp.c

123.c

這是原始文件(argp.c)末尾附近的源代碼。 您將看到我如何使用讀寫方法。

 while (count - ind > 1) {

        strcpy(cdir, argv[argc-1]);

        if (!isFile(cdir)) {
            strcat(cdir, basename(arguments.argv[ind]));
        }

        if (arguments.update) {
            stat(cdir,&stDest);
            stat(arguments.argv[ind],&stSrc);
            if (difftime(stDest.st_mtim.tv_sec, stSrc.st_mtim.tv_sec) > 0 ) {
                printf("Destination file is newer\n");
                exit(EXIT_FAILURE);
            }
        }

        //open source file
        src = open(arguments.argv[ind],O_RDONLY);
        //if source file can't be opened
        if (src == -1) {
            printf("\nError opening file %s errno = %d\n",arguments.argv[ind],errno);
            exit(EXIT_FAILURE);
        }

        //open target file
        if (arguments.force) {
            //with -f option(default)
            tgt = open(cdir, O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
        } else {
            //with -n option
            tgt = open(cdir, O_WRONLY | O_CREAT | O_EXCL , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
        }
        //if the target file cannot be read or already exist(with -n option)
        if (tgt == -1) {
            printf("File exist or it's not a file.\nCan't copy.\n");
            exit(EXIT_FAILURE);
        }

        //read source file


        //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, BUFFERSIZE) != pos) {
               exit(EXIT_FAILURE);
           }
        }

        //if the source file cannot be read
        if (pos == -1) {
            printf("\nError in reading data from %s\n",arguments.argv[ind]);
        }

        //close source file
        if (close(src) == -1) {
            printf("\nError in closing file %s\n",arguments.argv[ind]);
        }

        //close target file
        if (close(tgt) == -1) {
            printf("\nError in closing file %s\n",cdir);
        }

        ind++;
    }

    if (arguments.verbose) {
        printf("Copy successfully!\n");
    }

    exit(EXIT_SUCCESS);

}

這是復制文件末尾附近的源代碼(123.c)

        while (count - ind > 1) {

        strcpy(cdir, argv[argc-1]);

        if (!isFile(cdir)) {
            strcat(cdir, basename(arguments.argv[ind]));
        }

        if (arguments.update) {
            stat(cdir,&stDest);
            stat(arguments.argv[ind],&stSrc);
            if (difftime(stDest.st_mtim.tv_sec, stSrc.st_mtim.tv_sec) > 0 ) {
                printf("Destination file is newer\n");
                exit(EXIT_FAILURE);
            }
        }

        //open source file
        src = open(arguments.argv[ind],O_RDONLY);
        //if source file can't be opened
        if (src == -1) {
            printf("\nError opening file %s errno = %d\n",arguments.argv[ind],errno);
            exit(EXIT_FAILURE);
        }

        //open target file
        if (arguments.force) {
            //with -f option(default)
            tgt = open(cdir, O_WRONLY | O_CREAT | O_TRUNC , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
        } else {
            //with -n option
            tgt = open(cdir, O_WRONLY | O_CREAT | O_EXCL , S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
        }
        //if the target file cannot be read or already exist(with -n option)
        if (tgt == -1) {
            printf("File exist or it's not a file.\nCan't copy.\n");
            exit(EXIT_FAILURE);
        }

        //read source file


        //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, BUFFERSIZE) != pos) {
               exit(EXIT_FAILURE);
           }
        }

        //if the source file cannot be read
        if (pos == -1) {
            printf("\nError in reading data from %s\n",arguments.argv[ind]);
        }

        //close source file
        if (close(src) == -1) {
            printf("\nError in closing file %s\n",arguments.argv[ind]);
        }

        //close target file
        if (close(tgt) == -1) {
            printf("\nError in closing file %s\n",cdir);
        }

        ind++;
    }

if (arguments.verbose) {
    printf("Copy successfully!\n");
}

exit(EXIT_SUCCESS);

}
it(EXIT_FAILURE);
        }

        //read source file


        //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, BUFFERSIZE) != pos) {
               exit(EXIT_FAILURE);
           }
        }

        //if the source file cannot be read
        if (pos == -1) {
            printf("\nError in reading data from %s\n",arguments.argv[ind]);
        }

        //close source file
        if (close(src) == -1) {
            printf("\nError in closing file %s\n",arguments.argv[ind]);
        }

        //close target file
        if (close(tgt) == -1) {
            printf("\nError in closing file %s\n",cdir);
        }

        ind++;
    }

if (arguments.verbose) {
    printf("Copy successfully!\n");
}

exit(EXIT_SUCCESS);

}

您無條件地寫了一個完整的緩沖區,無論讀取了多少:

 //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, BUFFERSIZE) != pos) {
               exit(EXIT_FAILURE);
           }
        }

應該:

 //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, pos) != pos) {
               exit(EXIT_FAILURE);
           }
        }

您始終嘗試讀取/寫入BUFFERSIZE字節。 但是,如果要復制的文件的大小是BUFFERSIZE倍數,會發生什么? 您寫上次閱讀的內容。

read返回read的字節數,因此每次write應嘗試寫入此字節數:

代替:

        pos = read(src, buffer, BUFFERSIZE);

        //write target file
        while (pos > 0) {
            write(tgt, buffer, BUFFERSIZE);
            pos = read(src, buffer, BUFFERSIZE);
        }

采用:

        pos = read(src, buffer, BUFFERSIZE);

        //write target file
        while (pos > 0) {
            write(tgt, buffer, pos);
            pos = read(src, buffer, BUFFERSIZE);
        }

此處相同,而不是:

        //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, BUFFERSIZE) != pos) {
               exit(EXIT_FAILURE);
           }
        }

采用:

        //write target file
        while ((pos = read(src, buffer, BUFFERSIZE)) > 0) {
           if (write(tgt, buffer, pos) != pos) {
               exit(EXIT_FAILURE);
           }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM