此函数被传递到文本文件(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这是我要打开的文件的确切路径。
我怀疑该问题与此有关:
我正在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);