传递给嵌套函数的字符串文字指针问题
string literal pointer issue passing to nested functions
所以我有记录一些数据并将其写入文件的功能,return将文件路径作为字符串。
然后我需要获取该字符串并将其传递给解析文件并将数据放入结构中的函数
在文件可以被解析之前,字符串路径需要是 "transformed" 因此每个目录分隔符都包含反斜杠的转义字符。为此,我将字符串传递给另一个函数。
在高层次上,这似乎是一项非常容易的任务,但我相信我没有将原始的 return 字符串正确地传递给其他函数,因为当我检查控制台中的输出时transformed 我收到乱码。下面是我正在尝试做的一个简化示例。我知道我的转换方法不是问题,因为如果我将嵌套转换函数中的代码行放在 main() 中,一切都会顺利进行,所以这一定是我将指针传递给其他功能再尝试操作。
main(){
char* filePath = logData();
parseData(filePath);
}
int parseData(char* filePath){
char* transformFile = transFormPath(filePath);
//parse data from transformFile
return 0;
}
char* transFormPath(char* filePath){
//transform filePath to newPath
return newPath;
}
如有任何帮助,我们将不胜感激,
谢谢!
在 C 中,由于内存管理的原因,字符串操作不能有方便的接口。如果一个函数接收一个字符串,并将其转换为另一个字符串,您应该决定如何声明它的接口。
最简单的接口就地(strtok
使用它);仅当输出小于输入时才可以使用它:
void func(char* input_and_output);
一个更传统的界面是"output in pre-allocated buffer"(sprintf
使用它);仅当可以计算或以某种方式限制输出的大小时才可以使用它:
void func(const char* input, char* output);
另一个想法是"allocate the output dynamically"(asprintf
使用它);它没有限制,但更难使用:
char* func(const char* input);
它的缺点是它强加给调用者的责任 - 它必须 free
在将来某个时间分配的字符串。
让我们使用第三个接口:
char* transFormPath(const char* filePath)
{
char* newPath;
newPath = malloc(100); // is 100 enough? no idea
strcpy(newPath, "haha"); // just an example
return newPath;
}
int main()
{
...
char* filePath = "path";
char* newPath = transFormPath(filePath);
...
free(newPath);
}
如果您决定使用此接口,您的 transFormPath
函数 应该 动态分配字符串,调用者 应该在不再需要的时候释放字符串。这并非易事 - 通常 "time when the string is not needed" 不容易定义,如果您更改代码,调用 free
的安全时间可能会在您没有意识到的情况下发生变化。作为一种快速而肮脏的 hack,您可以在不释放内存的情况下编写代码(即故意引入内存泄漏)。
让我们使用第二个接口:
void transFormPath(const char* filePath, char* newPath)
{
// Here we assume newPath has enough space to hold the output
strcpy(newPath, "haha"); // just an example
}
int main()
{
...
char* filePath = "path";
char* newPath = malloc(100); // is 100 enough? no idea
transFormPath(filePath, newPath);
...
free(newPath);
...
char newPath2[100]; // is 100 enough? no idea
transFormPath(filePath, newPath2);
}
一个方便的经验法则是“malloc
和 free
应该在同一个函数中调用”——这个接口使得不违反它成为可能。
此外,此接口使得使用堆栈(自动)内存分配成为可能 - 如果对输出的大小有一些限制,只需在堆栈上分配最大可能的缓冲区。
所以我有记录一些数据并将其写入文件的功能,return将文件路径作为字符串。
然后我需要获取该字符串并将其传递给解析文件并将数据放入结构中的函数
在文件可以被解析之前,字符串路径需要是 "transformed" 因此每个目录分隔符都包含反斜杠的转义字符。为此,我将字符串传递给另一个函数。
在高层次上,这似乎是一项非常容易的任务,但我相信我没有将原始的 return 字符串正确地传递给其他函数,因为当我检查控制台中的输出时transformed 我收到乱码。下面是我正在尝试做的一个简化示例。我知道我的转换方法不是问题,因为如果我将嵌套转换函数中的代码行放在 main() 中,一切都会顺利进行,所以这一定是我将指针传递给其他功能再尝试操作。
main(){
char* filePath = logData();
parseData(filePath);
}
int parseData(char* filePath){
char* transformFile = transFormPath(filePath);
//parse data from transformFile
return 0;
}
char* transFormPath(char* filePath){
//transform filePath to newPath
return newPath;
}
如有任何帮助,我们将不胜感激, 谢谢!
在 C 中,由于内存管理的原因,字符串操作不能有方便的接口。如果一个函数接收一个字符串,并将其转换为另一个字符串,您应该决定如何声明它的接口。
最简单的接口就地(strtok
使用它);仅当输出小于输入时才可以使用它:
void func(char* input_and_output);
一个更传统的界面是"output in pre-allocated buffer"(sprintf
使用它);仅当可以计算或以某种方式限制输出的大小时才可以使用它:
void func(const char* input, char* output);
另一个想法是"allocate the output dynamically"(asprintf
使用它);它没有限制,但更难使用:
char* func(const char* input);
它的缺点是它强加给调用者的责任 - 它必须 free
在将来某个时间分配的字符串。
让我们使用第三个接口:
char* transFormPath(const char* filePath)
{
char* newPath;
newPath = malloc(100); // is 100 enough? no idea
strcpy(newPath, "haha"); // just an example
return newPath;
}
int main()
{
...
char* filePath = "path";
char* newPath = transFormPath(filePath);
...
free(newPath);
}
如果您决定使用此接口,您的 transFormPath
函数 应该 动态分配字符串,调用者 应该在不再需要的时候释放字符串。这并非易事 - 通常 "time when the string is not needed" 不容易定义,如果您更改代码,调用 free
的安全时间可能会在您没有意识到的情况下发生变化。作为一种快速而肮脏的 hack,您可以在不释放内存的情况下编写代码(即故意引入内存泄漏)。
让我们使用第二个接口:
void transFormPath(const char* filePath, char* newPath)
{
// Here we assume newPath has enough space to hold the output
strcpy(newPath, "haha"); // just an example
}
int main()
{
...
char* filePath = "path";
char* newPath = malloc(100); // is 100 enough? no idea
transFormPath(filePath, newPath);
...
free(newPath);
...
char newPath2[100]; // is 100 enough? no idea
transFormPath(filePath, newPath2);
}
一个方便的经验法则是“malloc
和 free
应该在同一个函数中调用”——这个接口使得不违反它成为可能。
此外,此接口使得使用堆栈(自动)内存分配成为可能 - 如果对输出的大小有一些限制,只需在堆栈上分配最大可能的缓冲区。