gpt4 book ai didi

c++ - fprintf 在特定字符串上失败,而 shell 函数使用它没有崩溃

转载 作者:行者123 更新时间:2023-11-27 22:38:21 25 4
gpt4 key购买 nike

简短版本:我有一个 C++ 代码,它使用对 fprintf(stdout, some_cpp_str.c_str()) 的 C 调用并在调用期间崩溃。前 4 次调用都很好,只有第 5 次崩溃,我不知道为什么 (怀疑字符串中有不可读的字符)。我发布的第一个代码主要是 C,所以我发布了另一个代码,除了 fprintf (代码添加在问题的底部)之外只有 C++。崩溃(始终)发生在嵌入式设备上。在我自己的 PC 上,代码运行良好


长版:

我有一个代码可以从文本中读取行,并将它们推送到一个字符串 vector 中。为了检查我的进度,我还在 vector 填充后 fprintf 将它们显示到屏幕上:

int main(){
char err_msg[256], * line = NULL, *in_file = "...", *keyword = "blah";
size_t len = 0;
ssize_t num_bytes_read;
int i = 1;
std::vector<std::string> lines_vector;

FILE * fp = fopen(in_file, "r");
if (!fp) {
fprintf(stdout,"can't open file %s for reading\n", in_file);
goto EXIT;
}

while ((num_bytes_read = getline(&line, &len, fp)) != -1) {
/* if found keyword inside line */
if (strstr(line, keyword)) {
/* add 3 lines (entry heading, entry body, newline)*/
lines_vector.push_back(std::string(line));
for(int lines_to_copy = 2; lines_to_copy > 0; lines_to_copy--) {
if((num_bytes_read = getline(&line, &len, fp)) == -1) {
fprintf(stdout,"can't read line from %s\n", in_file);
goto EXIT;
}
lines_vector.push_back(std::string(line));
}
}
}
fprintf(stdout,"finished reading from file\n");

EXIT:
fclose(fp);
free(line);

for (std::vector<std::string>::iterator it = lines_vector.begin() ; it != lines_vector.end(); ++it, ++i) {
fprintf(stdout, "%d)", i);
fprintf(stdout, "%s", (*it).c_str());
}
return 0;
}

这在我的 VM 上运行良好,但我也在嵌入式设备上运行它,它总是在特定线路上崩溃。该行是:

证书 local generate name localcert common-name sf country(region) AB auto-regenerate-days 12 auto-regenerate-days-warning 11 e-mail X@Y.com locality(city) Z organization Q organization -unit T scep-password-string 57E6CA35452E72E4D1BC4518260ABFC7 scep-url http://0.0.0.0/X/Y/state(province) s

我认为线路本身没有问题(因为它不会在我的 VM 上崩溃)。尝试将其打印到文件而不是屏幕时,它不会崩溃:

for (std::vector<std::string>::iterator it = lines_vector.begin(); it != lines_vector.end(); ++it){
sprintf(tmp, "echo \"%s\" >> /X/Y/Z.txt", (*it).c_str());
OS_run(tmp); // run this command on sh shell
}

因为它只在我的嵌入式而不是我的 VM 上崩溃,我认为文件不知何故损坏了。会不会是字符串内部有一个无效字符导致 fprintf 崩溃,而不是 echo


我尝试将此代码翻译成正确的 C++,但我仍然在最后一个字符串的中间发生崩溃。我知道混合使用 C/C++ 不好,但 c_str() 不应该是 std::string 和 char *(fprintf 期望)?

如果不是这样,那么什么可能会在 fprintf 期间崩溃?

int main()
{
std::vector<std::string> lines_vector;
std::ifstream infile(in_file);
std::string line;
int counter = 1;

while (std::getline(infile, line)) {
if (line.find(keyword, 0) != std::string::npos) {
lines_vector.push_back(line);
for(int lines_to_copy = 2; lines_to_copy > 0; lines_to_copy--) {
std::getline(infile, line);
lines_vector.push_back(line);
}
}
}

for (std::vector<std::string>::iterator it = lines_vector.begin(); it != lines_vector.end(); ++it){
fprintf(stdout, "%d)%s", counter++, (*it).c_str());
}
}

最佳答案

在嵌入式设备上,动态内存分配可能会失败。这意味着您绝对必须控制所有可能的分配(即使在非嵌入式设备上您也应该控制,但崩溃风险要低得多......)。你真的应该:

while ((num_bytes_read = getline(&line, &len, fp)) != -1) {
...
}
if (line == NULL) {
perror("getline could not allocate buffer");
}

这不会解决任何问题,但至少您会知道会发生什么。


我在这里尊重您的编码风格,大量使用 C 库并使用 goto .但我必须建议您不要在 C++ 程序中这样做。

C 库曾经包含在 C++ 标准库中,因为早期的 C++ 实现缺少太多功能。在现代 C++ 中 goto将被禁止,所有原始 C 字符串和 C io 函数也是如此(非常特殊的用例除外)。 C++ 附带一个版本 getline (在标题 <string> 中)直接填充 std::string .如果学习 C++,您真的应该尽量避免使用 C 构造。


根据 Ben Voigt 的评论,如果您想避免动态分配,则有使用旧式 C 库的正确用例。但在那种情况下,你也应该避免 std::stringstd::vector

关于c++ - fprintf 在特定字符串上失败,而 shell 函数使用它没有崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51382484/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com