【问题标题】:fopen: file does not exist but it doesfopen:文件不存在,但确实存在
【发布时间】:2017-10-19 11:17:41
【问题描述】:

我想读取在可执行文件所在的文件夹中可以找到的所有文件,但我正在运行的可运行文件除外。我编写了以下代码,但是,尽管此列表正确列出了我文件夹中的文件,但我无法使用 fopen 打开它们,因为 fopen 打印出该文件不存在。如果我执行 gedit “从我的 c 程序中获得的文件的路径”,那么它会从该术语完美打开。错误在哪里?

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

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

//Determining the number of files we have.
//We call to a bash command http://stackoverflow.com/questions/646241/c-run-a-system-command-and-get-output
FILE *fp, *fin;
char path[1035], cwd[1024];
int scanned = 0;

/* Open the command for reading. */
//https://askubuntu.com/questions/370697/how-to-count-number-of-files-in-a-directory-but-not-recursively
//This count soft and hard links also (I think)
fp = popen("ls -F |grep -v /", "r");
if (fp == NULL) {
    printf("Failed to run command\n" );
    exit(1);
}

/* Read the output a line at a time - output it. */
//Loop for each file. Be careful! if the exe is inside, it will also be counted!
while (fgets(path, sizeof(path)-1, fp) != NULL) {
    printf("Reading file: %s\n", path); 

    fin=fopen(path,"r");

    scanned = 0;
    printf("caa");

    if (fin != NULL){
        printf("AA\n");
        fclose(fin);
    }
    if (!fin)perror("fopen");
    printf("Done! \n");
}

/* close */
pclose(fp);

printf("end");

return 0;

}

【问题讨论】:

  • 试试printf("Reading file [%s]\n", path);
  • fopen 不打印任何东西!
  • 解析ls 输出是开销(进程创建、I/O)、脆弱(ls 可能丢失或版本不兼容)并且容易出错(请参阅您的问题)- 建议您使用您平台的 API 处理此类事情,请参阅 opendir()readdir()
  • 另外,不需要sizeof(path) - 1。只需使用sizeof(path)
  • 你可以——而且可能应该——避免使用你的popen;请参阅readdir(3)stat(2)nftw(3)... 并阅读Advanced Linux Programming

标签: c file unix fopen


【解决方案1】:

您的代码中有 2 个错误:

  1. 当代码更新代码中的“路径”变量时。它的末尾有一个换行符,需要更正为 NUL。这给出了不正确的路径。 可以将如下内容附加到您的代码中:

    while (fgets(path, sizeof(path)-1, fp) != NULL) {
    len=strlen(path);
    path[len-1]='\0';
    
  2. 使用“ls -A1”,因为“ls -F”在二进制名称中添加了一个“*”:

    fp = popen("ls -A1 |grep -v /", "r");

【讨论】:

    【解决方案2】:

    好的,以防万一其他人需要更好的方法,我用我拥有的 cmets 重新编写了代码。这里我给你新代码。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <dirent.h>             
    #include <sys/types.h>              
    #include <sys/stat.h>           
    
    int isDirectory(const char *path) {
       struct stat statbuf;
       if (stat(path, &statbuf) != 0)
           return 0;
       return S_ISDIR(statbuf.st_mode);
    }
    
    int main (int argc, char **argv) {
    
        FILE *fp, *fin;
        char path[1035], cwd[1024];
        int scanned = 0;
        int ints;
        DIR *dir;
        struct dirent *ent;
    
        //getcwd prints directory where the app ran.
        if ((dir = opendir (getcwd(cwd, sizeof(cwd)))) != NULL) {
            /* print all the files and directories within directory */
            while ((ent = readdir (dir)) != NULL) {
                /*Skips . and ..*/
                if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue;
                if (isDirectory(ent->d_name) != 0)                   continue;
    
                printf ("Reading file: %s\n", ent->d_name);
                scanned = 0;
                fin=fopen(ent->d_name,"r");
                if (fin != NULL){
                    while ((scanned = fscanf(fin, "%d", ints)) !=  EOF) {
                        if(scanned == 1){
                            printf("%d\n", ints);
                        }else {
                                printf("Whoops! Input format is incorrect!\n");
                            break;
                        }
                    } //LOOP: reading file
                    fclose(fin);
                }
                if (!fin)perror("fopen");
                printf("Done! \n");
            }//LOOP: while opendir
            closedir (dir);
        } else {
          /* could not open directory */
          perror ("opendir");
          return EXIT_FAILURE;
        }
    
      return 0;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-08
      • 2011-10-04
      • 2011-01-09
      • 2018-08-12
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 2017-02-07
      • 2014-06-20
      相关资源
      最近更新 更多