【C/C++】【File、Directory 文件、目錄】【待續】

目標:自動掃描新插入U盤文件,並複製制定類型文件到指定位置(本地、網絡)
階段:識別所有及新插入U盤;掃描文件;複製文件到本地位置;複製文件到網絡位置。

代碼 · 掃描文件

編譯環境 + 結果截圖
在這裏插入圖片描述

#pragma warning(disable : 4530)

#include <iostream>
#include <string.h>
#include <io.h>
using namespace std;

#define ArrLnt 200

void fnFind(char *fileName)
{
    char fileNameNew[ArrLnt];
    intptr_t findHandle;
    _finddata_t findData;

    strcpy(fileNameNew, fileName);
    strcat(fileNameNew, "\\*.*");
    findHandle = _findfirst(fileNameNew, &findData);

    if (findHandle == -1)
        return;

    static char indent[ArrLnt];
    strcat(indent, "  ");

    do
    {
        cout << indent << "|";
        if (findData.attrib == _A_SUBDIR)
        {
            strcpy(fileNameNew, fileName);
            strcat(fileNameNew, "\\");
            strcat(fileNameNew, findData.name);

            cout << fileNameNew << endl;

            if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0)
                continue;
            fnFind(fileNameNew);
            indent[strlen(indent) - 2] = '\0';
        }
        else
        {
            cout << findData.name << endl;
        }
    } while (_findnext(findHandle, &findData) == 0);

    _findclose(findHandle);
}

int main()
{
    char fileName[ArrLnt] = "C:\\Users\\Administrator\\Desktop\\c\\A";

    cout << "\n --- start --- \n"
         << endl;
    fnFind(fileName);
    cout << "\n --- end --- \n"
         << endl;

    return 0;
}

string 轉換爲 char *

錯誤:無法從 std::string 轉換爲 char *

C++ 將 std::string 轉換爲 char*,必須通過string對象的 c_str() 方法,獲取C-style的字符串。

string str = "1234";
cout << str.data() << endl;
cout << str.c_str() << endl;

[]、at()

vector 容器,效率使用[](可能會超出邊界)來訪問,穩定性使用at()來訪問。

_finddata_t、_findfirst、_findnext和_findclose

#include <io.h>

_finddata_t 文件信息結構體

_finddata_t 是用來存儲文件各種信息的結構體。

struct _finddata_t
{
    unsigned attrib;    // attribute
    time_t time_create; // # define time_t long
    time_t time_access; //
    time_t time_write;  //
    _fsize_t size;      // # define _fsize_t unsigned long
    char name[260];     //
};

file attribute 文件屬性

// File attribute constants for the _findfirst() family of functions
#define _A_NORMAL 0x00 // Normal file - No read/write restrictions
#define _A_RDONLY 0x01 // Read only file
#define _A_HIDDEN 0x02 // Hidden file
#define _A_SYSTEM 0x04 // System file
#define _A_SUBDIR 0x10 // Subdirectory 子目錄
#define _A_ARCH   0x20 // Archive file 存檔文件

_findfirst()

long _findfirst(const char *_FileName, struct _finddata_t *_FindData);

  • 第一個參數爲文件名,可以用*.*來查找所有文件,也可以用*.cpp來查找.cpp文件。
  • 第二個參數是_finddata_t結構體指針。若查找成功,返回文件句柄,若失敗,返回-1。
char *fileName = "C:";
intptr_t findHandle;
_finddata_t findData;
_findfirst(fileName, findData);

_findnext

intptr_t _findfirst64i32(const char *_FileName, _finddata64i32_t *_FindData)
第一個參數爲文件句柄,第二個參數爲_finddata_t結構體指針。若查找成功,返回0,失敗返回-1。

intptr_t findHandle;
_finddata_t findData;
_findnext(findHandle, &findData);

typedef long long intptr_t;

_findclose

int __cdecl _findclose(intptr_t _FindHandle);只有一個參數,文件句柄。若關閉成功返回0,失敗返回-1。

intptr_t findHandle;
_findclose(findHandle);

#pragma warning(disable : 4530)

#include <iostream>
#include <vector>
#include <string>
#include <cstring> // for strcat()

#include <stdlib.h>
#include <io.h>
using namespace std;

#define PathLength 200
vector<char *> getFilesList(char *dir)
{
    vector<char *> allPath;

    char dirNew[PathLength];

    strcpy(dirNew, dir);
    strcat(dirNew, "\\*.*"); // 在目錄後面加上"\\*.*"進行第一次搜索

    cout << dirNew << endl;
    system("pause");

    intptr_t handle;
    _finddata_t findData;

    if ((handle = _findfirst(dirNew, &findData)) == -1)
    { // 檢查是否成功
        cout << "can not found the file ... " << endl;
        return allPath;
    }

    do
    {
        if (findData.attrib & _A_SUBDIR) // 是否含有子目錄
        {
            // 若該子目錄爲"."或"..",則進行下一次循環,否則輸出子目錄名,並進入下一次搜索
            if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0)
                continue;

            cout << findData.name << "\t<dir>\n";
            // 在目錄後面加上"\\"和搜索到的目錄名進行下一次搜索
            strcpy(dirNew, dir);
            strcat(dirNew, "\\");
            strcat(dirNew, findData.name);

            vector<char *> tempPath = getFilesList(dirNew);
            allPath.insert(allPath.end(), tempPath.begin(), tempPath.end());
        }
        else //不是子目錄,即是文件,則輸出文件名和文件的大小
        {
            char *filePath = new char[PathLength];
            strcpy(filePath, dir);
            strcat(filePath, "\\");
            strcat(filePath, findData.name);

            allPath.push_back(filePath);
            cout << filePath << "\t" << findData.size << " bytes.\n";
        }
    } while (_findnext(handle, &findData) == 0);

    _findclose(handle); // 關閉搜索句柄
    return allPath;
}

int main()
{
    char dir[PathLength] = "C:\\Users\\Administrator\\Desktop\\c";
    // cout << "\nEnter a directory: ";
    // cin >> dir;

    cout << "\nOutput all file paths :" << endl;

    getFilesList(dir);
    // for (auto path : getFilesList(dir))
    //     cout << path << endl;

    return 0;
}

Directory 目錄

unistd.h

unistd.h在windows下面是沒有的 - 爲了孩子他娘 - CSDN博客

  • 在 Linux 下編寫的程序是默認包含這個頭文件的,不需要特別的去包含這個文件。
  • 在 windows 下面沒有這個東西,所以在 windows下面需要寫一下這個頭文件
    自建一個 unistd.h ,文件內容爲
#ifndef _UNISTD_H
#define _UNISTD_H
#include <io.h>
#include <process.h>
#endif /* _UNISTD_H */

其作用等同於 windows 下的 windows.h 。

chdir、getcwd

#include <stdio.h>
#include <direct.h>

int main(int argc, char *argv[])
{
    if (chdir(argv[1]) == -1)
    { // 將當前工作目錄切換到 argv[1](從命令行傳進來的路徑)
        perror("chdir");
        return -1;
    }
    printf("\n Current Working Directory : %s!\n", getcwd(NULL, 0));

    return 0;
}

getcwd

Get Current Working Directory

#include <stdio.h>
#include <direct.h>
int main()
{
    printf("\nCurrent Working Directory : %s\n", getcwd(NULL, 0));
    return 0;
}

fopen

FILE *fopen(const char *filename, const char *mode);
fopen - C++ Reference

mode

C string containing a file access mode.

mode
r read: Open file for input operations. The file must exist.
w write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.
a append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist.
r+ read/update: Open a file for update (both for input and output). The file must exist.
w+ write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.
a+ append/update: Open a file for update (both for input and output) with all output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations move the position back to the end of file. The file is created if it does not exist.

fscanf

fprintf

fclose

#include<stdio.h>
int main(){
    
    FILE *fp=fopen("in.txt","r");
    char cr;
    fscanf(fp,"%c",&cr);
    fclose(fp);
    
    fp=fopen("out.txt","w");
    fprintf(fp,"%c",cr);
    fclose(fp);
    
    return 0;
}

freopen

FILE * freopen ( const char * filename, const char * mode, FILE * stream );

  • FILE * stream 通常使用標準流文件(stdin/stdout/stderr)
freopen("in.txt","r",stdin); //輸入重定向,輸入數據將從in.txt文件中讀取
freopen("out.txt","w",stdout); //輸出重定向,輸出數據將保存在out.txt文件中

freopen("CON","r",stdin);   //從控制檯讀入
freopen("CON","w",stdout);//從控制檯輸出

fclose(stdin);//關閉文件
fclose(stdout);//關閉文件

把預定義的標準流文件定向到由 filename 指定的文件中。
標準流文件具體是指 stdin、stdout和stderr。其中

  • stdin是標準輸入流,默認爲鍵盤
  • stdout是標準輸出流,默認爲屏幕
  • stderr是標準錯誤流,默認爲屏幕。
    通過調用freopen,就可以修改標準流文件的默認值,實現重定向。

若要恢復句柄,可以重新打開標準控制檯設備文件,只是這個設備文件的名字是與操作系統相關的。

DOS/Windows
freopen("CON", "r", stdin);

Linux
freopen("/dev/console", "r", stdin);

system


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

int main()
{
    system("color 02");
    system("calc");
    system("title shotdown");
    // system("pause");
    printf("ha\n");
    Sleep(1000);
    system("cls");
    system("C:\\Users\\Administrator\\Desktop\\c\\c.txt");
    return 0;
}

/、…、. 根目錄、父目錄、當前目錄

/ 根目錄
…、…/ 上一層目錄(父目錄)
.、./ 當前目錄

文件路徑中 /、\ 斜槓、反斜槓區別


  • \ 一般是表示本地目錄的,C:\windows
  • / 主要表示遠程電腦或者網絡地址,https://www.baidu.com

U盤

C 用文件指針操作文件。
C++ 基於**文件流(即非標準的輸入輸出)**操作文件。

程序預期功能:自我複製,短暫等待後啓動(能否植入註冊表),讀取文件類型,刪除或加密文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章