Загрузка файла CSV в CLISTCTRL

Я не могу говорить на английском очень хорошо. Речь может быть неловкой при использовании переводчика.

Вопрос

Сохраните содержимое CLISTCTRL в виде файла .csv на C++. Я хочу снова загрузить сохраненное содержимое с помощью CLISTCTRL! Проблема в том, что при загрузке во время выполнения индексы от 0 до 10 отображаются нормально. Дублирующийся вывод происходит с 11-го индекса по 10-й индекс, а символы усекаются. Буду признателен, если вы сообщите мне, что не так в приведенном ниже коде и что нужно исправить!

файл Excel

Управление списком после вставки элементов

struct DATA 
{
    CString strName;
    CString strEmail;
    CString strTel;
    CString strGroup;
};

//Code to initialize CLISTCTRL
//CLISTCTRL control name = L_viewctrl

    FILE* file = NULL;
    DATA* indexData = new DATA;

    USES_CONVERSION;

    fopen_s(&file, path_str, "r");
    if (file)
    {
        char szContent[2048];

        memset(szContent, NULL, sizeof(szContent));

        CString strRstring;
        int nFileline(0);
        int nSubString(0);
        while (fgets(szContent, 2048, file))
        {
            //File Read
            CString strFile;
            strFile = szContent;

            bool bfileLineRet = TRUE;
            while (bfileLineRet)
            {
                AfxExtractSubString(strRstring, strFile, nSubString++, ',');
                if (nSubString == 2)indexData->strName = strRstring;

                if (nSubString == 3)indexData->strEmail = strRstring;

                if (nSubString == 4)indexData->strTel = strRstring;

                if (nSubString == 5) 
                {
                    indexData->strGroup = strRstring;
                    nSubString = 0;
                    bfileLineRet = FALSE;
                }
            }

            //LIST INDEX DATA SET;
            UpdateData(TRUE);
            CString strCount;
            strCount.Format(_T("%d"), nFileline);
            L_viewctrl.InsertItem(nFileline, strCount);
            L_viewctrl.SetItem(nFileline, 1, LVIF_TEXT, indexData->strName, 0, 0, 0, 0);
            L_viewctrl.SetItem(nFileline, 2, LVIF_TEXT, indexData->strEmail, 0, 0, 0, 0);
            L_viewctrl.SetItem(nFileline, 3, LVIF_TEXT, indexData->strTel, 0, 0, 0, 0);
            L_viewctrl.SetItem(nFileline, 4, LVIF_TEXT, indexData->strGroup, 0, 0, 0, 0);
            nFileline++;
        }
    }
    fclose(file);

Я попытался загрузить файл csv в LISTCTRL и распечатать значения. Я хотел нормально прочитать файл csv и вывести его в LISTCTRL, но Чтение и печать файла CSV прошли успешно. Однако до 10-го индекса он выводился нормально, но после этого вывод по 10-му индексу был перезаписан.

Совершенно непонятно, что здесь происходит. «выходные данные по 10-му индексу были перезаписаны»: что это должно означать? Не описывайте результат (каким бы он ни был), а покажите его. Отредактируйте и покажите изображение элемента управления списком и минимальный файл CSV. Я не вижу здесь ничего явно неправильного, кроме ужасного форматирования if (nSubString == 2)indexData->strName = strRstring;. Не жадничайте с пробелами.

Jabberwocky 16.04.2024 11:48

Другое дело: вызов UpdateData(TRUE); для каждой прочитанной строки кажется неправильным/ненужным.

Jabberwocky 16.04.2024 11:52

@Jabberwocky Спасибо, что ответили на мой пост. Содержимое csv-файла и результаты выполнения я разместил вверху поста. Буду признателен, если вы сообщите мне, если есть какие-либо проблемы или моменты, которые необходимо исправить. У меня новый вопрос! 1. Вы сказали не жадничать на пустом пространстве. Что это значит? 2.if (nSubString == 2)indexData->strName = strRstring; Вы сказали, что это ужасный код. Что нужно сделать, чтобы написать правильно?

포스제이 18.04.2024 03:22

Это не ужасный код, это ужасное форматирование: if (nSubString == 2)indexData->strName = strRstring;-> if (nSubString == 2) indexData->strName = strRstring;

Jabberwocky 18.04.2024 09:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что ваш список отсортирован в алфавитном порядке. Вы вызываете InsertItem(nFileline,... и затем предполагаете, что позиция только что вставленного элемента равна nFileline, но это не потому, что элементы вставлены в соответствии с алфавитной сортировкой. Например, элемент «10» вставляется после элемента «1» (это хорошо видно на опубликованном вами изображении).

Вы можете исправить проблему, используя значение, возвращаемое InsertItem, которое является индексом в списке, куда фактически был вставлен элемент.

Что-то вроде:

...
int index = L_viewctrl.InsertItem(nFileline, strCount);
L_viewctrl.SetItem(index, 1, LVIF_TEXT, indexData->strName, 0, 0, 0, 0);
L_viewctrl.SetItem(index, 2, LVIF_TEXT, indexData->strEmail, 0, 0, 0, 0);
...

Кроме того, вы можете установить для свойства «Сортировка» элемента управления «Список» значение «Нет». Вероятно, вам вообще не нужна сортировка, поскольку вы, вероятно, хотите, чтобы в элементе управления списком был тот же порядок, что и в файле CSV.


Кстати: вы наткнетесь на еще одну проблему: вставленные вами элементы будут потеряны навсегда. Вам нужно использовать CListCtrl::SetItemData, чтобы сохранить указатель на ваши данные в каждом элементе списка, что-то вроде.

...
int index = L_viewctrl.InsertItem(nFileline, strCount);
L_viewctrl.SetItemData(index, (DWORD_PTR)indexData);
...

В противном случае вы не сможете получить доступ к данным после вставки всех элементов в список. Если вам не нужны фактические данные, поскольку вы хотите отобразить только элемент управления списком, вам все равно придется удалить его. Каждая вещь, выделенная с помощью new, должна быть удалена с помощью delete.

Также не забудьте в конечном итоге удалить выделенные данные.

Другие вопросы по теме