用fgets的输出调用fopen

时间:2017-12-05 04:54:12

标签: c fopen fgets

我正在尝试使用fgets的输出从另一个文本文件中打开文件。

具体来说,我的" ./ list.txt"包含我想要打开的文件的所有相对路径。

例如,这就是list.txt的样子:

./tst/f/ak/1237743.txt
./tst/f/ak/1393387.txt
./tst/f/ak/276317o.txt
./tst/f/ak/44z5938.txt
.
.
.

等等。

我试图从这个" list.txt"获得一行。并将该输出用作另一个fopen调用的参数,从而导致打开" ./tst / f / ak / 1237743.txt"等等。

我制作了一个非常简单的代码,看看是否可以这样做。

这就是我的代码的样子:

int main()
{
    FILE *f;
    f = fopen("./list.txt", "r");
    if(f==NULL){

        printf("failed\n");
        return 1;
    }

    char tmp[255];
    char *addr;
    addr = fgets(tmp, sizeof(tmp), f);
    addr[strlen(addr)-1] = '\0';
    fclose(f);
    printf("%s\n", addr);

    FILE *x;
    x = fopen(addr, "r");
    if(x==NULL){

        printf("failure\n");
        return 1;
    }

    printf("Success\n");

    fclose(x);
}

这就是我得到的:

  

./ TST / F / AK / 1237743.txt

     

失败

对我做错的地方有任何帮助吗?

我也试过

fopen("./tst/f/ak/1237743.txt", "r)

它工作正常,所以我相信这里的相对路径没有任何问题......

1 个答案:

答案 0 :(得分:2)

将评论复制到答案中。

基本问题是您的数据文件具有CRLF(DOS样式)行结尾,但您正在使用未将CRLF映射到换行符的Unix计算机,这与Windows计算机不同。

  

您可以通过将名称括在例如方括号中来改进打印:

printf("[%s]\n", addr);
     

这将显示字符串addr中是否有换行符或回车符。我怀疑,这是你问题的原因。您可能会在与]不同的行上看到[。或者,您可能会在该行的开头看到],但根本看不到[

     

另外,您是在Unix衍生产品上还是在Windows上编译和运行?数据文件是否曾经在Windows机器上? (我猜你正在使用Linux,数据文件来自Windows。)

回应是:

  哇,你是对的。 [%s]\n显示“]./tst/f/ak/1237743.txt”。是的,我使用的是Ubuntu,但list.txt文件是从Windows机器创建的。这是问题的根源吗?

答案是:

  

这是你在换绳前的回车。 [...] - 您提供的配置信息是您遇到问题的根源; Unix(Linux,Ubuntu)机器上的Windows数据。

     

使用标记字符包围文本字符串的技巧通常可以很快诊断出这样的问题。值得记住。

再次:

  

谢谢!所以我想我必须创建一个全新的list.txt文件?

回复是:

  

你有几个选择。一种是创建一个新文件。您可以使用转换实用程序(例如dos2unix)来转换文件。或者您可以使用strcspn()代替strlen()来删除换行符或CRLF,如下所示:

addr[strcspn(addr, "\r\n")] = '\0';`
     

这会将null字节放在它遇到的第一个CR或LF上,或者如果没有CR或LF字符,则用空字节覆盖空字节(因此即使使用简并数据也是安全的)。