我是 C 编程的新手,我正在尝试打开一个 .txt 文件进行阅读。
我有一个文本文件,我想读取不同的文件名,每个文件在不同的行中。我创建了一个函数 txt_to_stations() 读取这个文件并返回一个指向 char 的双指针,我猜它必须是一个双指针,因为我想保存一串 char 字符串。这就是功能。
char** txt_to_stations(const char* txt_file) {
FILE* file;
file = fopen(txt_file, "r");
int line_count = 0;
int char_count = 0;
int len = 1;
char tmp_station[25];
char** stations = (char**)malloc(len*sizeof(char*));
char character;
while(!feof(file)) {
character = fgetc(file);
if(character != '\n') {
tmp_estation[char_count] = character;
char_count++;
}else if(character == '\n') {
stations = (char**)realloc(stations, len*sizeof(char*));
stations[line_count] = (char*)malloc(char_count*sizeof(char));
strcpy(stations[line_count], tmp_station);
len++;
line_count++;
char_count = 0;
}
}
fclose(file);
return stations;
}
我的文本文件是这个。 “站.txt”
weatherdata-429-81.csv
weatherdata-429-84.csv
weatherdata-429-88.csv
当我尝试从 main 函数读取这些文件时,问题就来了。该功能效果很好,因为如果我
char** stations = txt_to_stations("stations.txt")
然后例如
printf("station1: %s\n", stations[0])
它在终端中打印 weatherdata-429-81.csv
.
但是如果我在主函数中定义一个新文件
FILE* reading;
reading = fopen(stations[0]);
if(reading == NULL) {
printf("csv file cant be opened");
}
它打印“无法打开 csv 文件”,这意味着
fopen(stations[0]) == NULL
,但它不会,因为如果我简单地通过 fopen("weatherdata-429-81.csv")
更改站 [0] 它有效。这可能是一个菜鸟错误,但我明白stations[0] == weatherdata-429-81.csv (as char*)
我真的尝试过将
stations[0]
(char*) 转换为const char*,并且还在“stations.txt”中将每个名称写入双引号,但无论如何它根本不起作用。我该如何解决这个问题?
我通过调试器运行了你的代码,发现了一些错误。我为您评论了它们(以及其他一些要点)。
char** txt_to_stations(const char* txt_file)
{
FILE* file;
file = fopen(txt_file, "r");
if(file == NULL) // You forgot to error-check file. fopen is one
// of the most likely functions to return NULL,
// so you really can't forget that
{
printf("Error opening file.");
exit(0); // Exits your program, regardless of where
// you are, defined in stdlib.h
}
int line_count = 0;
int char_count = 0;
int len = 2; // I made len slightly bigger, nothing with a
// little bit of buffer and also allows you
// to keep space for the NULL terminator
char tmp_station[25] = {0}; // It is always a good idea to zero out
// an array you're creating. While testing
// I found some stray garbage characters
// at the end of one of the strings...
char** stations = (char**) malloc(len * sizeof(char*));
char character;
while (1) // This should run forever and you should break out
// of this loop when you reach the end of the file
{
// This is one way to properly find the end of a file.
// Don't put feof call inside the while condition
if (feof(file))
break;
// fgets() would save you a lot of time, but oh well,
// I don't want to change your code too much...
character = fgetc(file);
if(character != '\n')
{
tmp_station[char_count] = character;
char_count++;
}
else // Removed the if here because it was redundant... else
// it means that it must be a newline character
{
tmp_station[char_count] = '\0'; // You forgot to null-terminate
// the string you took into
// tmp_station. This is the
// main reason the function
// wasn't working
stations = (char**) realloc(stations, len*sizeof(char*));
stations[line_count] = (char*) malloc(char_count*sizeof(char));
strcpy(stations[line_count], tmp_station);
len++;
line_count++;
char_count = 0;
// It's a good idea to terminate an array of pointers
// with NULL. How will you know you reached the end
// of the array?
stations[line_count] = NULL;
}
}
fclose(file);
return stations;
}
到目前为止,您的代码存在一个小问题。看,因为你只将一行导入指针数组当且仅当找到换行符,这意味着如果你的
stations.txt
文件的最后一行没有换行符,该行将不会导入到大批。有两种解决方案。
weatherdata-429-81.csv
weatherdata-429-84.csv
weatherdata-429-88.csv
更改代码,无论是否有换行符,都可以导入最后一行。
使用
fgets()
。它将继续读取整个文件,直到到达文件末尾,因此您可以将它返回的任何内容存储在一个数组中,并手动删除它自己生成的换行符。