C++ Читая Маркеры файла

Этот дизайн не очень необычный, сравните также ошибочно в стандартном C.

Дизайн имеет ряд потенциальных преимуществ:

  • Функция не должна писать через указатель на успех. Это не только делает реализацию таких функций более легкой и менее подверженной ошибкам, но также может быть небольшим преимуществом в производительности (например, это предотвращает аннулирование кэшей ЦП при успешном выполнении функции).

  • Если мы всегда проверяем, что функция не сработала, прежде чем получить доступ к ошибке, мы можем использовать один и тот же указатель ошибки для нескольких функций. В противном случае мы можем получить предыдущий сбой, а не сбой самой последней функции.

  • Это облегчает написание кода проверки. Например. функция может установить ошибку по умолчанию. Если все проверки пройдены, функция может просто вернуть успех вместо того, чтобы сбрасывать переменную ошибки.

  • Функция может использовать тот же указатель ошибки при вызове других функций, но сбой этих помощников не обязательно означает сбой верхней функции.

В вашем конкретном случае переменная NSError *theError; не была инициализирована. Доступ к этой переменной без ее назначения вначале вызовет неопределенное поведение. Документация только гарантирует, что переменная будет установлена ​​в случае ошибки.

5
задан Martin York 9 November 2008 в 02:13
поделиться

3 ответа

Да оператор>> при использовании со строковым чтением 'пробел' разделил слова. 'Пробел' включает символы табуляции пространства и символы новой строки.

Если Вы хотите читать, строка во время используют станд.:: getline ()
Строка может затем маркироваться отдельно со строковым потоком.

std::string   line;
while(std::getline(std::cin,line))
{

    // If you then want to tokenize the line use a string stream:

    std::stringstream lineStream(line);
    std::string token;
    while(lineStream >> token)
    {
        std::cout << "Token(" << token << ")\n";
    }

    std::cout << "New Line Detected\n";
}

Маленькое дополнение:

Не используя getline ()

Таким образом, Вы действительно хотите смочь обнаружить новую строку. Это означает, что новая строка становится другим типом маркера. Так позволяет, предполагают, что Вам разделили слова 'пробелы' как маркеры и новая строка как ее собственный маркер.

Затем можно создать Тип маркера.
Затем все, что необходимо сделать, записать потоковые операторы для маркера:

#include <iostream>
#include <fstream>

class Token
{
    private:
        friend std::ostream& operator<<(std::ostream&,Token const&);
        friend std::istream& operator>>(std::istream&,Token&);
        std::string     value;
};
std::istream& operator>>(std::istream& str,Token& data)
{
    // Check to make sure the stream is OK.
    if (!str)
    {   return str;
    }

    char    x;
    // Drop leading space
    do
    {
        x = str.get();
    }
    while(str && isspace(x) && (x != '\n'));

    // If the stream is done. exit now.
    if (!str)
    {
        return str;
    }

    // We have skipped all white space up to the
    // start of the first token. We can now modify data.
    data.value  ="";

    // If the token is a '\n' We are finished.
    if (x == '\n')
    {   data.value  = "\n";
        return str;
    }

    // Otherwise read the next token in.
    str.unget();
    str >> data.value;

    return str;
}
std::ostream& operator<<(std::ostream& str,Token const& data)
{
    return str << data.value;
}


int main()
{
    std::ifstream   f("PLOP");
    Token   x;

    while(f >> x)
    {
        std::cout << "Token(" << x << ")\n";
    }
}
16
ответ дан 18 December 2019 в 08:32
поделиться

Я не знаю, почему Вы думаете std::getline плохо. Можно все еще распознать новые строки.

std::string token;
std::ifstream file("file.txt");
while(std::getline(file, token)) {
    std::istringstream line(token);
    while(line >> token) {
        std::cout << "Token :" << token << std::endl;
    }
    if(file.unget().get() == '\n') {
        std::cout << "newline found" << std::endl;
    }
}
2
ответ дан 18 December 2019 в 08:32
поделиться

Это еще один крутой и гораздо менее многословный способ, с которым я столкнулся для токенизации строк.

vector<string> vec; //we'll put all of the tokens in here 
string token;
istringstream iss("put text here"); 

while ( getline(iss, token, '\n') ) {
       vec.push_back(token);
}
1
ответ дан 18 December 2019 в 08:32
поделиться
Другие вопросы по тегам:

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