Как прочитать файл с разделителями-запятыми и вывести результаты на 3 в одной строке

not необходимо поместить реализацию в файл заголовка, см. альтернативное решение в конце этого ответа.

В любом случае причина, по которой ваш код не работает, что при создании экземпляра шаблона компилятор создает новый класс с заданным аргументом шаблона. Например:

template
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo f; 

При чтении этой строки компилятор создаст новый класс (назовем его FooInt), что эквивалентно следующему:

struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}

Следовательно, компилятор должен иметь доступ к реализации методов, чтобы создать экземпляр с аргументом шаблона (в данном случае int). Если эти реализации не были в заголовке, они не были бы доступны, поэтому компилятор не смог бы создать экземпляр шаблона.

Общим решением для этого является запись объявления шаблона в заголовок файла, затем реализовать класс в файле реализации (например, .tpp) и включить этот файл реализации в конец заголовка.

// Foo.h
template 
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"

// Foo.tpp
template 
void Foo::doSomething(T param)
{
    //implementation
}

Таким образом, реализация по-прежнему отделена от объявления, но доступен компилятору.

Другое решение состоит в том, чтобы сохранить реализацию отдельно и явно создать все экземпляры шаблона, которые вам понадобятся:

// Foo.h

// no implementation
template  struct Foo { ... };

//----------------------------------------    
// Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo;
template class Foo;
// You will only be able to use Foo with int or float

Если мое объяснение isn ' t достаточно ясно, вы можете взглянуть на C ++ Super-FAQ по этому вопросу .

1
задан Ruben_PH 16 January 2019 в 11:04
поделиться

2 ответа

Я не удержался, чтобы написать пакетный скрипт для выполнения твоей задачи. Данный скрипт называется reshape.bat, предоставьте входной текстовый файл в качестве аргумента командной строки, например:

reshape.bat "algtest_extract.txt"

Чтобы сохранить выходные данные в другом файле, скажем, algtest_reshaped.txt, сделайте следующее: [116 ]

reshape.bat "algtest_extract.txt" > "algtest_reshaped.txt"

Вот код (см. Все пояснительные замечания):

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_FILE=%~1" & rem // (file to process; `%~1` means first argument)
set "_COL=3"    & rem // (number of columns in the output data)
set "_SEP=,"    & rem // (separator character for input and output data)
set "_PAD="     & rem // (if defined, fill up last row with empty cells)

rem // Read from file:
< "%_FILE%" call :PROCESS

endlocal
exit /B


:PROCESS
    rem // Initialise variables:
    set "REST=" & rem // (remaining text string after the first separator)
    set "LINE=" & rem // (row collector for line/row to output)
    set "IDX=0" & rem // (column counter for output data)
    setlocal EnableDelayedExpansion
:READ
    rem // Read some text, 1023 characters/bytes at most:
    set "STR=" & set /P STR=""
    rem // Terminate loop if no more data are available:
    if not defined STR goto :END
    rem // Precede with potential remainder from previous loop:
    set "STR=!REST!!STR!"
:PARSE
    rem // Extract everything behind the first separator:
    if defined STR set "REST=!STR:*%_SEP%=!"
    rem // No separator had been found, so read more text:
    if "!REST!"=="!STR!" goto :READ
    rem // Extract part in front of first separator:
    for /F "delims=%_SEP%" %%I in ("ITEM=!STR!") do set "%%I"
    rem // Increment column counter:
    set /A "IDX+=1" & if !IDX! lss %_COL% (
        rem // Output line/row not yet complete, so go on assembling:
        set "LINE=!LINE!%_SEP%!ITEM!"
    ) else (
        rem // Output line/row complete, hence return it:
        echo(!LINE:*%_SEP%=!%_SEP%!ITEM!
        rem // Reset row collector and column counter:
        set "LINE=" & set /A "IDX=0"
    )
    rem // Keep on parsing using the remainder:
    set "STR=!REST!" & goto :PARSE
:END
    rem // Return potential remaining data:
    if defined _PAD (set /A "IDX=_COL-IDX-1") else (set /A "IDX=0")
    set "LINE=!LINE!%_SEP%!REST!"
    for /L %%I in (1,1,%IDX%) do set "LINE=!LINE!%_SEP%"
    if defined LINE echo(!LINE:*%_SEP%=!
    endlocal
0
ответ дан aschipfl 16 January 2019 в 11:04
поделиться

В notepad ++ нажмите Ctrl+H, установите режим поиска в "Regular expression", затем используйте шаблон поиска

([^,]+,[^,]+,[^,]+),

и повторите поиск с

\1\n

UPD

используйте шаблон поиска ((?:[^,]+,){500}), если вы хотите использовать 500 элементов вместо 3. Запятые в конце каждой строки можно заменить с помощью шаблона поиска ,$

0
ответ дан Dmitry Polyakov 16 January 2019 в 11:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: