簡體   English   中英

請解釋這個 C 代碼有什么問題?

[英]Please explain What's wrong with this C code?

我想要的是獲取目錄中存在的所有文件,然后向該文件添加 .enc 擴展名。 示例-讓 File.txt 存在然后我將執行一些與加密相關的任務,之后新文件名將是 File.txt.enc

這是我的代碼:

#include <dirent.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    DIR *d;
    struct dirent *dir;
    char *name;
    int val;
    d = opendir(".");
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            name=dir->d_name;
            printf("File Found:%s\n",name);
            strcat(name,".enc");
            val=rename(dir->d_name,name);
            if(val==0)
                    printf("Encrypted File:%s\n",name);
            else
                    perror("Error: ");
        }
        closedir(d);
    }
    return(0);
}

但我得到這樣的輸出......

File Found:write_pgm_img.c
Error: : No such file or directory
File Found:realloc.c
Error: : No such file or directory
File Found:getusage.txt
Error: : No such file or directory
File Found:directory.c
Error: : No such file or directory

正如您所看到的“沒有這樣的文件或目錄”錯誤。 但我不明白為什么? 請解釋。提前致謝。

你搞亂了指針和內存內容:

            name=dir->d_name;
            printf("File Found:%s\n",name);
            strcat(name,".enc");
            val=rename(dir->d_name,name);

在第一行之后, namedir->d_name指向同一個內存地址。 這意味着您嘗試在dir->d_name所在的內存中添加后綴。 你不能指望內存足夠大來保存你的后綴。 (但在這種情況下,這不會導致問題,因為您的文件名似乎足夠短)

此外,您的更新將以相同的方式影響namedir->d_name ,這使得重命名毫無意義,因為您嘗試將getusage.txt.enc重命名為getusage.txt.enc

一個可能的解決方案可能是:

        char name[sizeof(dir->d_name)+4];
        while ((dir = readdir(d)) != NULL)
        {
            strcpy(name, dir->d_name);
            printf("File Found:%s\n",name);
            strcat(name,".enc");
            val=rename(dir->d_name,name);

您的namedir->d_name具有相同的地址。 因此strcat(name,".enc"); 將更新name & dir->d_nam並且源將具有前綴'.enc'

我想也許您假設name=dir->d_name創建了一些名為name新數據。 這是一個很容易犯的錯誤,因為在許多編程語言中,這正是會發生的事情。 但是,在 C 中,您剛剛設置了一個名為name的指針來引用名為d_name的現有數據。

如果你想向d_name附加一些東西,你可能需要將它復制到一個char * ,它引用一塊足夠大的存儲空間來容納它,以及后綴和終止空值,然后將后綴復制到它的末尾新的存儲。 就像是:

char *new_name = malloc (strlen (dir->d_name) + strlen (suffix) + 1);
strcpy (new_name, dir->d_name);
strcat (new_name, suffix);
...
free (new_name);

可能還有許多其他方法可以實現相同的目標。 基本點是在 C 中分配指針類型不會分配或復制存儲。

由於name可能沒有更大的尺寸, strcat(name,".enc"); will 可能會寫超過該大小並導致 UB。 正如其他人指出的那樣,這不會導致您得到 ENOENT 錯誤(假設您使用 linux)。

要解決這個問題,您必須創建一個新的、足夠大的緩沖區並將新名稱復制到其中。 這也將修復您得到的錯誤,因為這樣您就不會覆蓋舊名稱。

暫無
暫無

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

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