c_str () строка - все остальные строки, кроме первой, теряются

0

У меня есть строка, которая содержит несколько строк текста.

Например,

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

Это то, как обычно выглядит строка.

Когда я преобразовал этот stringstream в строку, информация была такой же.

Однако, когда я преобразовал это в строку 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
    @kfsone stream << std::endl эквивалентен stream << '\n' << std::flush . Почему OP должен использовать std::endl ?
  • 0
    Что такое "сообщение"? Какова цель "msg2"? Является ли msg std :: string? Если это так, избавьтесь от msg2 и используйте msg.assign(ss.str().c_str(), std::min(ss.str().size(), 10000);
Показать ещё 15 комментариев
Теги:
string

3 ответа

2
Лучший ответ

std::string вероятно, имеет встроенные символы '\0' (NUL), которые преждевременно завершают последовательность char, когда она интерпретируется как строка C.

Попробуйте std::remove NUL байты с помощью std::remove.

Изменить - это может быть вашей проблемой:

             lastmod.at(lastmod.size()-1) = '\0';

Это просто просит неприятностей. std::string точно хранит ваш байт NUL и копирует его в выходной файл.

  • 0
    Огромное спасибо!!
  • 0
    +1 и @ user2418202 примите во внимание мой комментарий в общих комментариях выше. Если вы думаете, что это «работает», исправляя это, но возвращаете указатель на локальный буфер в функции, подумайте еще раз.
Показать ещё 3 комментария
1

Эти строки выглядят подозрительными:

string lastmod(lm);
lastmod.at(lastmod.size()-1) = '\0';

Вставка нулевого символа в середину экземпляра класса строки, вероятно, создает неожиданное поведение (например, преждевременное завершение строки при печати).

Я не думаю, что вам нужно это сделать. Просто попробуйте удалить строку lastmod.at.

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню