fopen在变量文件路径上失败

问题描述 投票:0回答:1

此函数被传递到文本文件(mapper_path)的路径,该文件包含每行上其他文本文件的路径。我应该打开mapper_path.txt文件,然后打开并评估其中的每个路径(输出示例)。fopen在mapper_path文件上成功,但是在它包含的路径上失败。在失败情况下,它会打印我尝试打开的确切路径。我正在Windows的C语言环境中工作,并在Ubuntu子系统上运行命令。

如何正确读取子路径并将其存储到变量中以打开它?

已解决:我使用了有人建议的strcspn(txt_path,“ \ r \ n”)函数,对此一无所知,也没有添加'\ r'。谢谢!!

int processText(char * mapper_path, tuple * letters[])
{
    char line[LINE_SIZE];
    char txt_path[MAX_PATH];

    FILE * mapper_fp = fopen(mapper_path, "r");
    if(!mapper_fp)
    {
       printf("Failed to open mapper path: %s \n", mapper_path);
       return -1;
    }
      //!!! PROBLEM IS HERE !!!
    while(fgets(txt_path, MAX_PATH, mapper_fp))
    {
       //remove newline character from end
       txt_path[strlen(txt_path)-1] = 0;

       //open each txt file path, return -1 if it fails
       FILE* fp = fopen(txt_path, "r");
       if(!fp)
       {
          printf("Failed to open file path:%s\n", txt_path);
          return -1;
       } 
       //...more unimportant code

印刷品:无法打开文件路径:/mnt/c/users/adam/documents/csci_4061/projects/blackbeards/testtext.txt这是我要打开的文件的确切路径。

c string fopen filepath
1个回答
4
投票

我怀疑该问题与此有关:

我正在Windows的C语言环境中工作,并在Ubuntu子系统上运行命令。

大概是您使用Windows工具创建的mapper.txt文件,因此它具有Windows行尾。但是,我认为Ubuntu子系统不知道Windows行尾,因此,即使您以模式'r'打开文件,它也不会将CR-LF转换为单个\n。然后,在输入末尾删除\n时,仍然保留\r

\r在您打印出该行时将不可见,因为它所做的只是将光标移至该行的开头,下一个字符输出为\n。在打印调试消息时,通常将字符串与其他文本括起来通常是一个好主意,因为这可以为您提供有关此类问题的线索。如果您使用过:

printf("Failed to open file path: '%s'\n", txt_path);

您可能已经看到错误:

'ailed to open filepath: '/mnt/c/users/adam/documents/csci_4061/projects/blackbeards/testtext.txt

在这里,在字符串末尾有\r的提示是消息的第一个字符后缀有撇号。


[fgets“在[读取的行]的末尾添加\n字符并不是很准确。”准确地说,它不会删除该字符(如果存在)。该行的末尾很可能没有换行符。例如,该行可能是文本文件中不以换行符结尾的最后一行。否则fgets可能已达到您提供的字符数限制,而不是找到换行符而终止。

因此,使用getline接口肯定会更好,它具有两个优点:(a)它为线路本身分配存储空间,因此您无需事先猜测最大长度,并且(b)准确地告诉您阅读了多少个字符,因此您不必计数它们。

使用该信息,您可以删除恰好位于行尾的\n(如果有一个,然后删除前面的\r,如果有一个:]]

char* line = NULL;
size_t n_line = 0;
for (;;) {
    ssize_t n_read = getline(&line, &n_line, mapper_fp);
    if (n_read < 0) break;  /* EOF or some kind of read error */
    if (n_read > 0 && line[n_read - 1] == '\n') 
        line[nread--] = 0;
    if (n_read > 0 && line[n_read - 1] == '\r') 
        line[nread--] = 0;
    if (nread == 0) continue;  /* blank line */
    /* Handle the line read */
 }
 if (ferr(mapper_fp))
    perror("Error reading mapper file");
 free(line);
© www.soinside.com 2019 - 2024. All rights reserved.