0

我一直在尝试在 Ubuntu 20.04LTS 上运行这个非常简单的 C 代码

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

int main()
{
   
    FILE *f;
   
    f=fopen("tree.txt","r");
    if(f==NULL){
        perror("fopen");
        exit(1);
    }
    //readTree();
    return 0;
}

但无论我到目前为止尝试了什么 fopen 仍然返回这个错误:

fopen: No such file or directory
[1] + Done     

我假设的第一件事是程序没有打开文件的权限,但权限设置正确:

ls -la tree.txt
-rw-rw-rw- 1 mor mor 7 mar 26 20:43 tree.txt

接下来我尝试将文件的位置更改为 /home 或指定完整路径而不是文件名;还是一样的结果

现在是我无法理解的部分,在 Strace 下运行脚本时,它似乎工作正常,至少现在

execve("./B1", ["./B1"], 0x7ffe586e59b0 /* 26 vars */) = 0
brk(NULL)                               = 0x55cd150ea000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fff084d4590) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=156877, ...}) = 0
mmap(NULL, 156877, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcadcd70000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360q\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029224, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcadcd6e000
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\t\233\222%\274\260\320\31\331\326\10\204\276X>\263"..., 68, 880) = 68
mmap(NULL, 2036952, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcadcb7c000
mprotect(0x7fcadcba1000, 1847296, PROT_NONE) = 0
mmap(0x7fcadcba1000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7fcadcba1000
mmap(0x7fcadcd19000, 303104, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7fcadcd19000
mmap(0x7fcadcd64000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fcadcd64000
mmap(0x7fcadcd6a000, 13528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcadcd6a000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7fcadcd6f540) = 0
mprotect(0x7fcadcd64000, 12288, PROT_READ) = 0
mprotect(0x55cd14c84000, 4096, PROT_READ) = 0
mprotect(0x7fcadcdc4000, 4096, PROT_READ) = 0
munmap(0x7fcadcd70000, 156877)          = 0
brk(NULL)                               = 0x55cd150ea000
brk(0x55cd1510b000)                     = 0x55cd1510b000
openat(AT_FDCWD, "tree.txt", O_RDONLY)  = 3
exit_group(0)                           = ?
+++ exited with 0 +++

openat() 调用返回一个小的正整数,这是我目前阅读的正常行为

最后,真正让我大吃一惊的是,上面 Strace 的输出与我几分钟前收到的输出不同。出于某种原因,我似乎无法重新创建该输出,但它的要点是:

-openat() 返回 3

- lseek(fd, -9, SEEK_CUR)被调用并返回-1 ESPIPE 非法搜索请原谅我的语法,我是凭记忆写的。另外为什么偏移量是负整数?这正常吗?

为什么 lseek() 前几次被调用,但不是现在?

在这里阅读 lseek 上的 man它说

在 Linux 上,在终端设备上使用 lseek() 失败并出现错误 ESPIPE。

还有错误描述符

ESPIPE fd 与管道、套接字或 FIFO 相关联。

我相信第一个引用是不相关的,网上有很多线程,人们设法在 linux 上使用 fopen()。当涉及到错误描述符时,它超出了我的理解水平。

错误案例截图

渲染器1.log:

[2021-03-27 23:08:46.895] [renderer1] [error] Unexpected: The specified task is missing an execution: Error: Unexpected: The specified task is missing an execution
    at S.getTaskExecution (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:48749)
    at S.$onDidStartTaskProcess (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:46905)
    at c._doInvokeHandler (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:10509)
    at c._invokeHandler (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:10201)
    at c._receiveRequest (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:8871)
    at c._receiveOneMessage (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:7673)
    at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:90:5782
    at g.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:57:1836)
    at p.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:15443)
    at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:106:29119
    at g.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:57:1836)
    at p.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:15443)
    at t._receiveMessage (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:20693)
    at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:17587
    at g.fire (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:57:1836)
    at l.acceptChunk (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:12808)
    at /snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:65:12156
    at Socket.E (/snap/code/59/usr/share/code/resources/app/out/vs/workbench/services/extensions/node/extensionHostProcess.js:106:12375)
    at Socket.emit (events.js:315:20)
    at addChunk (_stream_readable.js:295:12)
    at readableAddChunk (_stream_readable.js:271:9)
    at Socket.Readable.push (_stream_readable.js:212:10)
    at Pipe.onStreamRead (internal/stream_base_commons.js:186:23)

这就是我能想到的,显然它还不够好。

任何和所有的帮助表示赞赏。

4

1 回答 1

0

总结一下,我的问题是 .c 程序的工作目录和我保存 .txt 文件的目录不同。有很多方法可以解决这个问题。

尝试在 fopen 目录中使用绝对路径。例如:

    FILE*f; f=fopen("/home/user/Desktop/file.txt","r");
 

这仅作为测试起作用,因为它使代码过于僵化(@kaylum 提供的答案)

使用chdir()更改工作目录

将目录更改为用户指定的目录的简单代码,以用户指定的名称和模式打开文件;使用getcwd()打印 cwd (@ilkkachu 提供的部分答案)

//puts cwd in *str and prints cwd if successful, otherwise prints error 
void getdir(char *str, unsigned int str_size)
{
    
     if(getcwd(str,str_size)==NULL){
        perror("getcwd()");
        exit(1);
    }else
        printf("Current working dir: %s\n",str);
}

//reads directory path and sets it as new working dir
int changeDir()
{
    char cwd[256];
    printf("New woking dir path= ");
    scanf("%s",cwd);
    if(chdir(cwd)!=0){
        perror("chdir()");
        return -1;
        }
    getdir(cwd,sizeof(cwd));
    return 0;
}

int main()
{
   
    FILE *f;
    char cwd[256],fmod[5];
    
    getdir(cwd,sizeof(cwd));
    //reads new path until an existing one is inputted
    while(changeDir()!=0);

    printf("File name: ");
    scanf("%s",cwd);
    printf("File mode: ");
    scanf("%s",fmod);
    
    f=fopen(cwd,fmod);
    if(f==NULL){
        perror("fopen");
        exit(1);
    }


    //reads first line of file and prints it to console
    fscanf(f,"%[^\n]",cwd);
    printf("%s",cwd);
    
    return 0;
}

代码终端输出:

Current working dir: /home/moro/Documents/TP-Lab
New woking dir path= /home/moro/doesNotExist
chdir(): No such file or directory
New woking dir path= /home/moro/Desktop
Current working dir: /home/moro/Desktop
File name: input.txt
File mode: r
THIS IS A TEST FILE[1] + Done

        

在 Visual Studio Code 设置中更改当前工作目录

设置>终端>集成:Cwd

您可以在那里指定起始路径

终端 › 集成:Cwd 将启动终端的显式启动路径,用作 shell 进程的当前工作目录 (cwd)。如果根目录不是方便的 cwd,这在工作区设置中可能特别有用。

可能有更流畅的方法来解决这个问题,但对于我的用例来说,这些选项已经足够好了。如果我找到时间,我会为这个答案添加更多解决方案

于 2021-03-28T12:30:40.520 回答