字符串文字指针问题传递给嵌套函数

时间:2016-10-06 12:57:40

标签: c string function pointers string-literals

所以我有记录一些数据并将其写入文件的函数,并以字符串形式返回文件的路径。

然后我需要获取该字符串并将其传递给一个解析文件并将数据放在结构中的函数

在解析文件之前,字符串路径需要“转换”,因此每个目录定界符都包含反斜杠的转义字符。为此,我将字符串传递给另一个函数。

在高级别,这似乎是一个非常简单的任务,但我相信我没有正确地将原始返回字符串传递给其他函数,因为当我在转换后检查控制台中的输出时,我会收到乱码。下面是我想要做的简化示例。我知道我的转换方法不是问题,因为如果我采用嵌套转换函数中的代码行并将它们放在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;

}

任何帮助将不胜感激, 谢谢!

1 个答案:

答案 0 :(得分:1)

在C中,由于内存管理,字符串操作无法提供方便的界面。如果函数接收到一个字符串,并将其转换为另一个字符串,则应决定如何声明其接口。

最简单的接口是就地的(strtok使用它);只有当输出小于输入时才能使用它:

void func(char* input_and_output);

更传统的接口是在预先分配的缓冲区中输出" (sprintf使用它);只有在可以计算或以某种方式限制输出大小的情况下才能使用它:

void func(const char* input, char* output);

另一个想法是"动态分配输出" (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函数应该动态分配字符串,并且调用者应该在某个时间释放该字符串#39;不再需要了。这不是一件容易的事 - 通常是不需要字符串的时间"不容易定义,如果您更改了代码,那么在没有您意识到的情况下,可以安全地调用free的时间会发生变化。作为一个快速而肮脏的黑客,您可以在不释放内存的情况下编写代码(即故意引入内存泄漏)。

让我们使用第二个界面:

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);
}

一个方便的经验法则是#34; mallocfree应该在同一个函数中调用" - 此界面可以不违反它。

此外,此接口可以使用堆栈(自动)内存分配 - 如果输出大小有一些限制,只需在堆栈上分配最大可能的缓冲区。