sprintf нарушение доступа к чтению исключения местоположения

Я прохожу курс программирования на C и столкнулся с ошибкой, которую не могу решить, как бы сильно ни старался.

Программа инструктирует меня: Запросить у пользователя первые 12 цифр номера EAN, затем вычислить 13-ю цифру безопасности, выполнив следующие операции:

Сложить вторую, четвертую, шестую, восьмую, десятую и двенадцатую цифры Сложить первую, третью, пятую, седьмую, девятую и одиннадцатую цифры Умножить первую сумму на 3 и прибавить ко второй сумме Вычесть 1 из общей суммы Вычислить остаток при делении скорректированной суммы на 10. Вычтите остаток из 9.

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

Вот мой код:

#include <stdio.h>

int main(void)
{
    long ean;       //creates variable to store a 12 digit integer
    int digits[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //initializes a 1x12 integer array
    printf("Please enter the first 12 digits in your EAN: ");
    scanf_s("%ld", &ean);   //collects the appropriate user input and stores it in ean
    char seperated[12];     //creates character array
    **sprintf_s(seperated, "%ld", ean); //converts the long integer ean to a string called separated
    for (int i = 0; i < 12; i++)
    {
        sscanf_s(seperated[i], "%d", &digits[i]);   //iterates through the characters and converts each one to an integer
                                                    //stored in the array created earlier
        printf("%d\n", digits[i]);
    }
    int sumEvens = digits[1] + digits[3] + digits[5] + digits[7] + digits[9] + digits[11]; //sums the even digits
    int sumOdds = digits[0] + digits[2] + digits[4] + digits[6] + digits[8] + digits[10]; //sums the odd digits

    int total = (3 * sumEvens + sumOdds)-1;     //multiplies the first sum by 3 and adds it to the second sum, 
                                                //then subtracts one from the total
    int securityDigit = 9 - (total % 10);   //Computes the remainder when the total is divided by 10 and subtracts that from 9
    return 0;
}

Проблема в том, что мой оператор sprintf (отмеченный **) выдает исключение, говорящее

Exception thrown at 0x0FB7373A (ucrtbased.dll) in ECE1400_2.exe: 0xC0000005: Access violation reading location 0xBE991A6D.

Кто-нибудь знает, что я делаю неправильно и как я могу это исправить? Я надеюсь, что это просто что-то маленькое, но я смотрел на это и исследовал более 2 часов.


person Ryan Zaugg    schedule 22.09.2020    source источник
comment
Номер, который вы вводите для ean, не длиннее 11 цифр? Помните, что строки на самом деле называются заканчивающимися нулем байтовыми строками. У вас также должно быть место для нулевого терминатора.   -  person Some programmer dude    schedule 22.09.2020
comment
Внимательно прочитайте документацию sprintf_s и sscanf_s.   -  person Jabberwocky    schedule 22.09.2020
comment
Подсказка: вам не нужно sscanf_s для чтения однозначных цифр. Это излишне, и в любом случае вы можете использовать sscanf_s только для строк с завершением NUL. Кроме того, если long имеет ширину 32 бита на вашей платформе, вы не можете иметь 11-значные целые числа, поскольку они превышают 32 бита. Вы, вероятно, должны рассматривать свой номер EAN как строку.   -  person Jabberwocky    schedule 22.09.2020


Ответы (3)


там много ненужного.

int main()
{
    char s[12] = {0};
    int n = 0;
    int digits[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; //initializes a 1x12 integer array
    printf("Please enter the first 12 digits in your EAN: ");
    for (int i = 0; i < 12; i++)
    {
        scanf("%d", &digits[i]);
    }
    int sumEvens = digits[1] + digits[3] + digits[5] + digits[7] + digits[9] + digits[11]; //sums the even digits
    int sumOdds = digits[0] + digits[2] + digits[4] + digits[6] + digits[8] + digits[10]; //sums the odd digits

    int total = (3 * sumEvens + sumOdds)-1;     //multiplies the first sum by 3 and adds it to the second sum, 
                                                //then subtracts one from the total
    int securityDigit = 9 - (total % 10);   //Computes the remainder when the total is divided by 10 and subtracts that from 9
    
    for (int i = 0; i <= 11; i++) {
        n += sprintf (&s[n], "%d", digits[i]);
    }

}
person Hermanto Kho    schedule 22.09.2020
comment
У меня был вопрос о вашем первом заявлении for, не попытается ли ваш scanf прочитать весь 12-значный номер EIN в цифры [i]? Как программа узнает, где начинается одно целое и другое? - person Ryan Zaugg; 22.09.2020

Вы, вероятно, хотите сделать что-то вроде этого

int main(void)
{
    int a[5]={1,2,3,1,3};
    char s[9] = {0};
    int n = 0;

    for (int i = 0; i < 5; i++) {
        n += sprintf (&s[n], "%d", a[i]);
    }

    printf ("\n char* s = %s\n\n", s);

    return 0;
}

вместо того, чтобы сделать его длинным.

и вам не нужно использовать sscanf_s, как указано в комментариях.

person Lorale    schedule 22.09.2020

Это было бы началом:

int main(void)
{
  __int64  ean;                       // using 64 bit integer

  int digits[12] = { 0 };             // one zero is enough

  printf("Please enter the first 12 digits in your EAN: ");
  scanf_s("%lld", &ean);              // using %lld here because ean is a 64 bit type
  char seperated[12];

  sprintf_s(seperated, 12, "%lld", ean); // also using %lld

  for (int i = 0; i < 12; i++)
  {
    digits[i] = seperated[i] - '0';   // I let you find out yourself about this "magic"
    printf("%d\n", digits[i]);
  }
  ...
person Jabberwocky    schedule 22.09.2020