无法获取std::string数组大小,两种方法均返回0的问题求助
问题根源与解决方案
核心问题:数组传参退化与C风格可变参数的误用
你在write_test里用std::string lines...这种C风格可变参数接收数组,这是错误的:
- 当原生数组
strs传入函数时,数组会自动退化为指针,此时sizeof(lines)获取的是指针的字节数(64位系统下为8),sizeof(lines[0])是std::string的大小(通常24),整数除法8/24结果为0,导致range为0,循环完全不执行,文件自然为空。 - C风格可变参数
...无法正确处理类型明确的数组,这种方式既不安全也无法推导数组长度。
三种可行解决方案
方案1:用模板推导数组大小(适合固定大小的原生数组)
通过模板引用传递数组,让编译器自动推导数组元素数量,避免数组退化:
template <size_t N> void write_test(std::string (&lines)[N]) { std::fstream fs(this->fp.c_str(), std::fstream::out); size_t range = N; std::cout << range; std::string grand_string; // 前range-1个元素添加换行,最后一个元素直接拼接 for (size_t i = 0; i < range - 1; ++i) { grand_string += lines[i] + "\n"; } // 处理空数组的边界情况 if (range > 0) { grand_string += lines[range - 1]; } // 检查文件是否成功打开 if (fs) { fs << grand_string; } fs.close(); this->scan(); }
调用方式不变,编译器会自动推导N=3,此时range正确为3。
方案2:改用std::vector(推荐,更符合C++风格)
放弃原生数组,使用std::vector<std::string>,它自带size()方法获取元素数量,且更灵活安全:
main.cpp修改:
std::vector<std::string> strs = {str1, str2, str3}; fs.write_test(strs);
write_test函数修改:
void write_test(const std::vector<std::string>& lines) { std::fstream fs(this->fp.c_str(), std::fstream::out); size_t range = lines.size(); std::cout << range; std::string grand_string; for (size_t i = 0; i < range - 1; ++i) { grand_string += lines[i] + "\n"; } if (range > 0) { grand_string += lines[range - 1]; } if (fs) { fs << grand_string; } fs.close(); this->scan(); }
这种方式支持动态增减元素,传递引用避免拷贝,代码可读性和安全性更高。
方案3:手动传递数组大小(兼容原生数组的妥协方案)
如果必须使用原生数组,可以在调用时手动传入数组长度:
main.cpp修改:
std::string strs[]={str1, str2, str3}; // 手动传入数组实际大小 fs.write_test(strs, 3);
write_test函数修改:
void write_test(std::string lines[], size_t range) { std::fstream fs(this->fp.c_str(), std::fstream::out); std::cout << range; std::string grand_string; for (size_t i = 0; i < range - 1; ++i) { grand_string += lines[i] + "\n"; } if (range > 0) { grand_string += lines[range - 1]; } if (fs) { fs << grand_string; } fs.close(); this->scan(); }
注意:这种方式需要手动保证传入的大小和实际数组长度一致,容易出错,不推荐。
额外修正点
原代码中循环条件i < range-2是错误的:当range=3时,range-2=1,只会循环1次(处理第一个元素),漏掉第二个元素。正确的条件是i < range-1,确保前range-1个元素都添加换行,最后一个元素直接拼接,避免末尾空行。
内容的提问来源于stack exchange,提问作者Formik Dev
相关产品推荐
相关产品推荐

