Nano Hash - криптовалюты, майнинг, программирование

С++ выводит дублирующиеся строки, когда есть '\n'

У меня возникли проблемы с этой функцией-членом класса. По сути, он предназначен для перевода слов на другой язык с сохранением той же пунктуации и пробелов. lineToTranslate — входной аргумент, представляющий собой массив слов, пробелов и знаков препинания. Каждое слово в нем должно быть отдельно взято из строки и переведено с помощью функции dict.translate(). Это работает правильно.

Однако проблема в том, что при наличии нескольких новых строк выводится предыдущая строка слов. Кроме того, пробелы не полностью обслуживаются. Если в предложении более одного пробела, выводится только один пробел. Любая идея о том, где я могу ошибаться? Любая помощь будет действительно оценена.

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

int len = strlen(lineToTranslate);
string strComplete = "";
const char *cs;

for (int x = 0; x < len; x++)
{
    if (!isspace(lineToTranslate[x]))
    {   
        char temp[MAX_WORD_LEN];
        int j = 0;

        while(lineToTranslate[x] != ' ' && lineToTranslate[x] != '\t' && lineToTranslate[x] != '\n')
        {
            temp[j] = lineToTranslate[x];
            x++;
            j++;
        }
        temp[j] = '\0';

        char returned[MAX_WORD_LEN];

        if(temp[0] != '\0')
        {
            dict.translate(returned, temp);
            strComplete = strComplete + returned;
        }
    }

    else
    {
        strComplete = strComplete + lineToTranslate[x];
        x++;
    }
}
cs = strComplete.c_str();
strcpy(translatedLine, cs);
10.05.2013

  • Я думаю, вам нужно немного больше контроля над циклом, чем вы думали сначала. Я считаю, что идея, которую вы пытаетесь конкретизировать, состоит в том, чтобы скопировать все данные из исходной строки в цель, но выбрать каждое слово и заменить его в переводе словаря. Очевидно, вы намереваетесь использовать пробелы или знаки препинания в качестве разделителей слов, а упомянутые пробелы и знаки препинания должны быть сохранены, но слова, которые они разделяют, заменены. Это точная оценка вашего намерения с этим кодом? 10.05.2013
  • это ispunct ваш код, если да, можем ли мы увидеть его реализацию? Я предполагаю, что поведение, которое вы наблюдаете, может быть связано с его реализацией. 10.05.2013
  • @Bill Рискну предположить, что ispunct(), вероятно, является реализацией из стандартной библиотеки, но было бы неплохо знать наверняка. 10.05.2013
  • Спасибо за помощь WhozCraig. Да, поэтому массив, который передается в качестве входного аргумента, для начала разбивается на слова по пробелам. Итак, эта часть работает нормально, и слова переводятся так, как ожидалось. Однако эти пробелы не остаются такими же, как исходный массив. выводится только один пробел, когда их должно быть два. Также строки повторяются, когда вместо новой строки есть два символа новой строки. 10.05.2013
  • я вижу еще одну возможную ошибку - когда ваш цикл for повторяется для spaces или punctuation, которые не подходят для входа в цикл while, вы все еще выполняете strComplete = strComplete + returned;, который добавляет \0 в середине без какой-либо причины, поэтому у вас есть выходная строка вроде -- <space>\0<space>\0 ..имеет смысл? 10.05.2013
  • Да, ispunct() — это реализация из стандартной библиотеки. 10.05.2013
  • Не могли бы вы попробовать поместить strComplete = strComplete + returned; внутрь if и посмотреть, поможет ли это? Ваш массив равен uninitialized, когда он не входит в if(temp[0] != '\0'), поэтому вам не следует добавлять returned... это определенно проблема. 10.05.2013
  • также не должны ли эти две строки быть вне цикла for ?? cs = strComplete.c_str(); strcpy(translatedLine, cs); 10.05.2013
  • @Bill Я думаю, вы поняли это, поставив cs = strComplete.c_str(); strcpy (переведенная строка, cs); вне цикла. Думаю, нужно еще немного испытаний. Это остановило дублирование строк там, где в любом случае есть две новые строки. Спасибо большое за вашу помощь. 10.05.2013
  • хорошо, я отправил ответ - к вашему сведению .. если есть еще проблемы, пожалуйста, дайте мне знать. 10.05.2013
  • Спасибо @Билл. Я дам вам знать, если возникнут какие-либо проблемы, если что-то нужно будет обновить. 10.05.2013
  • Привет @Билл. Я обновил код рекомендуемыми исправлениями, и они работают очень хорошо. Единственная проблема, с которой я столкнулся сейчас, заключается в том, что пробелы не добавляются по мере необходимости между словами. Там, где есть 2 пробела подряд, вводится один пробел, а там, где есть один пробел, ничего не вводится и слова выводятся следующим образом. 10.05.2013
  • @Michael Вам не нужно x++; в блоке else, об этом должен позаботиться ваш цикл for :) 10.05.2013
  • Кроме того, как работает ваша логика, если lineToTranslate[x] является space, вы не увеличиваете x, но цикл for увеличивает значение, поэтому вы пропускаете пробел... поэтому вы можете добавить x-- после temp[j] = '\0';, чтобы следующая итерация заняла space... надеюсь, это поможет... дайте мне знать, если это не исправит это. 10.05.2013
  • Это точно @Bill. Теперь код работает на 100%. Большое спасибо за вашу помощь, мне потребовались бы месяцы, чтобы понять все это! 10.05.2013

Ответы:


1

Когда ваш цикл for выполняет итерацию для spaces или punctuation, которые не подходят для входа в цикл while, вы все еще выполняете strComplete = strComplete + returned;, который добавляет \0 в середине без какой-либо причины, поэтому у вас есть выходная строка вроде -- <space>\0<space>\0

См. раздел значения по умолчанию в массиве.

Поэтому решение состоит в том, чтобы поместить strComplete = strComplete + returned; внутрь if. Ваш массив неинициализируется, когда он не входит в if(temp[0] != '\0'), поэтому вы не должны добавлять returned.

Далее... две строки ниже должны быть вне цикла for, так как вы хотите, чтобы окончательный результат strComplete копировался в translatedLine вместо каждой итерации.

cs = strComplete.c_str(); 
strcpy(translatedLine, cs);
10.05.2013

2

Для пробела я могу сказать, что для первого пробела он проверит условие if, затем итерация завершится, и мы вернемся к циклу for, x увеличивается, и теперь lineToTranslate[x]=' '. Правильный? Итак, цикл while никогда не запускается. Если условие if (temp[0]!='\0') выполнено. Итак, что же готовит return? Он не инициализирован. Ура все еще добавляет его. Может быть, я не очень помог, но это то, что я понял. Попробуйте отладку.

10.05.2013
  • Спасибо за вашу помощь, Раббиа. 10.05.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..