Хобрук: Ваш путь к мастерству в программировании

sscanf для сканирования строки определенного размера

Я хочу, чтобы в приведенном ниже коде сканировалась только строка «sizeof (out)» «out». Строка «input» может быть больше, чем out, и, следовательно, out может создать переполнение. Строка формата также может быть выполнена с помощью sprintf/snprintf.

#include<stdio.h>
#define BUFSZ 4

int main()
{
  char input[16]="#123 abcdefg";
  int k;
  char out[BUFSZ];

  sscanf(input,"#%d %s",&k,out);
  /* Something like %ns where n is the size of out in above line */ 

  printf("%d\n",k);
  printf("%s\n",out);
  return 0;
}
20.07.2013


Ответы:


1

Вам нужно создать другую строку, которая будет использоваться в качестве строки формата для sscanf. Это позволяет вставить размер строки (BUFSZ) в строку формата.

  char format_str[20];

  sprintf(format_str, "#%%d %%%ds", BUFSZ - 1);
  sscanf(input,format_str,&k,out);
20.07.2013

2

Я немного расширил приведенные выше объяснения и предоставил исполняемое объяснение с некоторыми тестовыми примерами, чтобы вы могли просмотреть свои варианты проверки.

#include<stdio.h>
#define BUFSZ 4

void PrintLine() { printf("---------------------------\n"); }

int MyIntegerScan(const char* input, int * integer, char * outbuf, size_t outbufSize)
{
    char format_str[20];
    sprintf(format_str, "%s%d%s", "#%d %n%", outbufSize -1 ,"s%n%*s%n");
    //"#%d %n%4s%n%*[^]%n"
    // ^----------------'#'   Character
    //    ^-------------' '   Any ammoutn of whitespace
    //   ^--------------%d    Decimal
    //        ^---------%4s   String Limited to 4 charcters, leave space for terminating zero
    //      ^---^-----^-%n    how many characters were read
    //             ^----%*[^] match anything without storing it

    int check0 = 0, check1 = 0, check2 = 0;

    printf("input: '%s'\n", input);
    *integer = 0;
    *outbuf = 0;

    int count = sscanf(input, format_str, integer, &check0, outbuf, &check1, &check2);

    switch (count)
    {
        case 0: printf("did not find number and string\n"); break;
        case 1: printf("did not find string\n"); break;
        case 2: printf("found both\n"); break;
        default: printf("unexpected error during scanf\n"); break;
    }

    if (check1 < check2)
        printf("unmatched rest: '%s'\n", input + check1);

    if (check1 == check2 && count == 2) 
        printf("length exactly as expected\n");

    if (check1 == check2 && count != 2)
        printf("did not fully match\n");

    if ((check1 - check0) < (outbufSize - 1) && count >= 2)
        printf("length shorter than expected\n");

    printf("matched: '%d' '%s'\n", *integer, outbuf);
    PrintLine();
    return 0;
}

int main()
{
    char out[BUFSZ];
    int k;

    //I want to have only "sizeof(out)" string 'out' to be scanned in the below code. 
    PrintLine();
    MyIntegerScan("#123 abc", &k, out, BUFSZ); //Happy Path
    MyIntegerScan("#123      abc", &k, out, BUFSZ); //A lot of whitespace
    MyIntegerScan("#123 a", &k, out, BUFSZ); //Input Very Short
    MyIntegerScan("#123 a noise", &k, out, BUFSZ); //Input Very Short Followed by noise
    MyIntegerScan("#123 abcdefg", &k, out, BUFSZ); //Input Too Long
    MyIntegerScan("#123", &k, out, BUFSZ); //Missing Text
    MyIntegerScan("# asdf", &k, out, BUFSZ); //Missing Number

    return 0;
}
03.04.2018
Новые материалы

5 проектов на Python, которые нужно создать прямо сейчас!
Добро пожаловать! Python — один из моих любимых языков программирования. Если вы новичок в этом языке, перейдите по ссылке ниже, чтобы узнать о нем больше:

Dall-E 2: недавние исследования показывают недостатки в искусстве, созданном искусственным интеллектом
DALL-E 2 — это всеобщее внимание в индустрии искусственного интеллекта. Люди в списке ожидания пытаются заполучить продукт. Что это означает для развития креативной индустрии? О применении ИИ в..

«Очень простой» эволюционный подход к обучению с подкреплением
В прошлом семестре я посетил лекцию по обучению с подкреплением (RL) в моем университете. Честно говоря, я присоединился к нему официально, но я редко ходил на лекции, потому что в целом я нахожу..

Освоение информационного поиска: создание интеллектуальных поисковых систем (глава 1)
Глава 1. Поиск по ключевым словам: основы информационного поиска Справочная глава: «Оценка моделей поиска информации: подробное руководство по показателям производительности » Глава 1: «Поиск..

Фишинг — Упаковано и зашифровано
Будучи старшим ИТ-специалистом в небольшой фирме, я могу делать много разных вещей. Одна из этих вещей: специалист по кибербезопасности. Мне нравится это делать, потому что в настоящее время я..

ВЫ РЕГРЕСС ЭТО?
Чтобы понять, когда использовать регрессионный анализ, мы должны сначала понять, что именно он делает. Вот простой ответ, который появляется, когда вы используете Google: Регрессионный..

Не зря же это называют интеллектом
Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..