使用 fgets 的输出调用 fopen
Calling fopen with an output from 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] = '[=11=]';
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
failure
对我做错的地方有帮助吗?
我也试过了
fopen("./tst/f/ak/1237743.txt", "r)
它工作正常,所以我确信这里的相对路径没有问题...
正在将评论复制到答案中。
基本问题是您的数据文件具有 CRLF(DOS 样式)行尾,但您正在使用不将 CRLF 映射到换行符的 Unix 机器,这与 Windows 机器不同。
You could improve the printing by enclosing the name in, for example, square brackets:
printf("[%s]\n", addr);
This would show whether there is a newline, or perhaps a carriage return, in the string addr. And that, I suspect, is the cause of your problem. You'd probably see the ]
on a different line from the [
. Alternatively, you might see the ]
at the start of the line and not see the [
at all.
Also, are you compiling and running on a Unix derivative or on Windows? Was the data file ever on a Windows machine? (I guess you're using Linux and the data file came from Windows.)
回应是:
Wow, you are right. [%s]\n
shows "]./tst/f/ak/1237743.txt
". And yes, I am using Ubuntu but the list.txt
file was created from a Windows machine. Is this the source of the problem?
答案是:
That's a carriage return before the newline that you zap. […] Yes — the configuration information you give is the source of your trouble; Windows data on a Unix (Linux, Ubuntu) machine.
The trick of surrounding text strings with marker characters can often diagnose problems like this quite quickly. It's worth remembering.
再一次:
Thank you! So I guess I have to create a whole new list.txt
file?
回应是:
You have a couple of options. One would be to create a new file. You could use a conversion utility such as dos2unix
to convert the file. Or you could strip newlines or CRLF by using strcspn()
instead of strlen()
, like this:
addr[strcspn(addr, "\r\n")] = '[=11=]';`
That will put the null byte at the first CR or LF it encounters, or overwrite the null byte with a null byte if there are no CR or LF characters (so it is safe, even with degenerate data).
我正在尝试从另一个文本文件中打开带有 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] = '[=11=]';
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
failure
对我做错的地方有帮助吗?
我也试过了
fopen("./tst/f/ak/1237743.txt", "r)
它工作正常,所以我确信这里的相对路径没有问题...
正在将评论复制到答案中。
基本问题是您的数据文件具有 CRLF(DOS 样式)行尾,但您正在使用不将 CRLF 映射到换行符的 Unix 机器,这与 Windows 机器不同。
You could improve the printing by enclosing the name in, for example, square brackets:
printf("[%s]\n", addr);
This would show whether there is a newline, or perhaps a carriage return, in the string addr. And that, I suspect, is the cause of your problem. You'd probably see the
]
on a different line from the[
. Alternatively, you might see the]
at the start of the line and not see the[
at all.Also, are you compiling and running on a Unix derivative or on Windows? Was the data file ever on a Windows machine? (I guess you're using Linux and the data file came from Windows.)
回应是:
Wow, you are right.
[%s]\n
shows "]./tst/f/ak/1237743.txt
". And yes, I am using Ubuntu but thelist.txt
file was created from a Windows machine. Is this the source of the problem?
答案是:
That's a carriage return before the newline that you zap. […] Yes — the configuration information you give is the source of your trouble; Windows data on a Unix (Linux, Ubuntu) machine.
The trick of surrounding text strings with marker characters can often diagnose problems like this quite quickly. It's worth remembering.
再一次:
Thank you! So I guess I have to create a whole new
list.txt
file?
回应是:
You have a couple of options. One would be to create a new file. You could use a conversion utility such as
dos2unix
to convert the file. Or you could strip newlines or CRLF by usingstrcspn()
instead ofstrlen()
, like this:addr[strcspn(addr, "\r\n")] = '[=11=]';`
That will put the null byte at the first CR or LF it encounters, or overwrite the null byte with a null byte if there are no CR or LF characters (so it is safe, even with degenerate data).