我有一个字符串流,其中包含多行文字。
例如,
f.html Sat Oct 19 22:59:47 2013 23675
folder Mon Nov 4 19:36:14 2013 4096
readdirpractice.cpp Tue Nov 5 03:00:10 2013 1203
server.cpp Mon Nov 4 21:22:27 2013 11369
photo.jpg Wed Oct 23 01:45:04 2013 4360
qq Sun Nov 3 01:54:36 2013 66031
server.cpp~ Mon Nov 4 21:22:25 2013 11368
myhttp.cpp Sun Nov 3 01:43:09 2013 1816
getoptpractice.cpp~ Sun Nov 3 01:15:25 2013 1324
这就是字符串流通常的样子。
当我将此字符串流转换为字符串时,信息是相同的。
但是,当我将其转换为C字符串时,它只占用第一行,而其他所有行都会丢失。
它只有
f.html Sat Oct 19 22:59:47 2013 23675
转换后。
为什么会这样,我该如何解决?
我附上了部分代码。
if(is_dir) {
char dirname[1024];
strncpy(dirname, requests[1].c_str(), sizeof(dirname));
dirname[sizeof(dirname)-1] = 0;
DIR *d;
struct dirent *dir;
d = opendir(dirname);
stringstream ss;
if (d) {
while ((dir = readdir(d)) != NULL) {
char* file = dir->d_name;
if(file[0] != '.') {
struct stat sb;
if (stat(file, &sb) == -1) {
cerr << "stat error" << endl;
exit(EXIT_FAILURE);
}
char* lm = ctime(&sb.st_mtime);
string lastmod(lm);
lastmod.at(lastmod.size()-1) = '\0';
string spacing = " ";
ss << file << spacing.substr(0, spacing.size() - strlen(file)) << lastmod << spacing.substr(0, spacing.size() - lastmod.size()) << sb.st_size << '\n';
}
}
closedir(d);
}
//cout << ss.str() << endl; // for testing
char msg2[10000];
strncpy(msg2, ss.str().c_str(), sizeof(msg2));
msg2[sizeof(msg2)-1] = 0;
msg = msg2;
答案 0 :(得分:2)
std::string
可能嵌入了'\0'
个(NUL)字符,当它被解释为C字符串时会过早地终止char
序列。
尝试使用std::remove
删除NUL字节。
编辑 - 这可能是您的问题:
lastmod.at(lastmod.size()-1) = '\0';
这只是在惹麻烦。 std::string
忠实地存储了您的NUL字节并将其复制到输出中。
答案 1 :(得分:1)
根据评论,您表示“msg”是返回值。
char msg2[10000];
strncpy(msg2, ss.str().c_str(), sizeof(msg2));
msg2[sizeof(msg2)-1] = 0;
msg = msg2;
“msg2”正在创建为局部变量,即在堆栈上。然后,您将字符串流复制到此堆栈区域,获取字符串的地址(在堆栈上),然后离开您的函数,此时堆栈区域将被释放并由应用程序的其他部分使用。
您需要在堆上为字符串分配内存,否则您需要从调用函数传入存储。
由于您已经在进行字符串操作,因此使用std :: string来封装管理开销将是最合乎逻辑的。引用标准字符串作为参数:
void getDirListing(std::string& msg) {
}
然后用
打电话std::string dirListing = "";
getDirListing(dirListing);
答案 2 :(得分:1)
这些行看起来很可疑:
string lastmod(lm);
lastmod.at(lastmod.size()-1) = '\0';
将空字符串插入字符串类实例的中间可能会产生意外行为(例如打印时字符串提前终止)。
我认为你不需要这样做。只需尝试删除lastmod.at
行。