cs50: pset1: кредит: застрял, все введенные карты недействительны

#c #cs50 #fgets

#c #cs50 #фгеты

Вопрос:

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

РЕДАКТИРОВАТЬ Извините, ребята, я расскажу немного больше о проблеме, потому что в моем сообщении для нее предоставлено слишком мало информации. Так что в основном я должен реализовать алгоритм Луна. Согласно алгоритму Луна, вы можете определить, является ли номер кредитной карты (синтаксически) допустимым следующим образом:

Умножьте каждую вторую цифру на 2, начиная со предпоследней цифры номера, а затем сложите цифры этих продуктов вместе. Добавьте сумму к сумме цифр, которые не были умножены на 2. Если последняя цифра суммы равна 0 (или, говоря более формально, если сумма по модулю 10 равна 0), число является действительным!

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];

int n = strlen(ccnum);

for (int i = 0; i<16; i  )
{
    ccnumber[i] = ccnum[i] -'0';
}


int ccnumber_m[7];
for (int i = 0; i < 16; i =2)
{
    ccnumber_m[i] = ccnumber[i]*2;
}
int sum = 0;
for (int i = 0; i < 8; i  )
{
     if (ccnumber_m[i] > 9)
     {
         sum  = (ccnumber_m[i] % 10)   1;
     }
     else
     {
        sum  = ccnumber_m[i];
     }
     printf("%dn", sum);
}


for (int i = 1; i < 16; i =2)
{
    sum  = ccnumber[i];
}

if (sum%10 == 0)
{
    if ( (n == 15) amp;amp; (ccnumber[0] == 34 || ccnumber[0] == 37))
    {
        printf("AMEXn");
    }
    else if ((n == 16) amp;amp; (ccnumber[0] == 51 || ccnumber[0] == 52 ||ccnumber[0] == 53 || ccnumber[0] == 54 || ccnumber[0] == 55))
    {
        printf("MASTERCARDn");
    }
    else if ((n == 13 || n == 16) amp;amp; ccnumber[0] == 4)
    {
        printf("VISAn");
    }
}    
else
{
    printf("INVALIDn");
}
 

}

Я добавил printf в свою переменную sum, чтобы увидеть, где программа терпит неудачу, и именно здесь, похоже, все идет наперекосяк. Каждый раз, когда я запускаю его, появляются разные значения суммы ?! Заранее благодарю.

Комментарии:

1. Например: int ccnumber_m[7]; for (int i = 0; i < 16; i =2) { ccnumber_m[i] = ccnumber[i]*2; } — вы получаете доступ ccnumber_m за пределы, поскольку в нем всего 7 элементов, индексированных от 0 до 6, да, вы доступ до 15… Если вы используете GCC, скомпилируйте с -Wall -Wextra -O3 -fsanitize=undefined,address , чтобы увидеть, какие странные вещи вы делаете…

2. Что ccnumber[0] == 34 вы имели в виду ccnumber[0] == 0x34 ? Лучше проверить наличие фактических цифр , которые вы хотите: ccnumber[0] == '4' . Аналогично с ccnumber[0] == 52 но: вы уже выполнили корректировку ASCII в первом цикле с ccnumber[i] = ccnum[i] -'0'; помощью .

3. извините, ребята, я просто отредактировал проблему и предоставил немного больше информации об этом.

4. ‘ccnumber [i] = ccnum [i] -‘0′;’ записывает вне пределов для i = 15.

5. Ваш код просто полон ошибок OOB, range и fencepost obi-wan. Как насчет того, чтобы везде, где вы обращаетесь к массиву, вы распечатывали используемый вами индекс, чтобы вы могли их проверить.

Ответ №1:

Хорошо, ребята, нашли решение. Да, я перепутал большинство своих циклов и диапазонов массивов, и условия были повсюду. Внес некоторые изменения в мой код в целом, и еще через несколько часов код работает так, как ожидалось. Вот обновленный код. Уверен, что код может быть более кратким и может быть решен намного быстрее. Завтра снова взгляну на это, чтобы обдумать больше идей и найти способы быстрее решить проблему.

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
printf("type a credit card number: ");
char ccnum[17];
fgets(ccnum, 17, stdin);
int ccnumber[15];

int n = strlen(ccnum);
int counter = 0;


for (int i = 0; i < n; i  )
{
    ccnumber[i] = ccnum[i] -'0';
    if (ccnumber[i] >= 0)
    {
        counter   ;
    }
}
int sum = 0;
if (counter == 16)
{

    int ccnumber_m[7];
    int index = 0;
    for (int i = counter - 2; i > -1 ; i-=2, index  )
    {
        ccnumber_m[index] = ccnumber[i]*2;
    }
    
    for (int i = 0; i < 8; i  )
    {
         if (ccnumber_m[i] > 9)
         {
             sum  = (ccnumber_m[i] % 10)   1;
         }
         else
         {
            sum  = ccnumber_m[i];
         }
    }
     for (int i = 1; i < counter   1; i =2)
     {
        sum  = ccnumber[i];
     }

}
else if (counter == 15)
{
    int ccnumber_m[6];
    int index = 0;
    for (int i = counter-2; i > 0; i-=2, index  )
    {
        ccnumber_m[index] = ccnumber[i]*2;
    }
    
    for (int i = 0; i < 7; i  )
    {
         if (ccnumber_m[i] > 9)
         {
             sum  = (ccnumber_m[i] % 10)   1;
         }
         else
         {
            sum  = ccnumber_m[i];
         }
    } 
    
     for (int i = 0; i < counter   1; i =2)
     {
        sum  = ccnumber[i];
     }
}
else if(counter == 13)
{
    int ccnumber_m[5];
    int index = 0;
    for (int i = counter-2; i > 0; i-=2, index  )
    {
        ccnumber_m[index] = ccnumber[i]*2;
    }
    
    for (int i = 0; i < 6; i  )
    {
         if (ccnumber_m[i] > 9)
         {
             sum  = (ccnumber_m[i] % 10)   1;
         }
         else
         {
            sum  = ccnumber_m[i];
         }
    } 
    
     for (int i = 0; i < counter   1; i =2)
     {
        sum  = ccnumber[i];
     }   
}
else
{
    printf("INVALIDn");
    return 0;
}


if (sum%10 == 0)
{
    if ((counter == 15) amp;amp; ((ccnumber[0] == 3 amp;amp; ccnumber[1] == 4) || (ccnumber[0] == 3 amp;amp; ccnumber[1] == 7)))
    {
        printf("AMEXn");
    }
    else if ((counter == 16) amp;amp; ((ccnumber[0] == 5 amp;amp; ccnumber[1] == 1) || (ccnumber[0] == 5 amp;amp; ccnumber[1] == 2) || (ccnumber[0] == 5 amp;amp; ccnumber[1] == 3) || (ccnumber[0] == 5 amp;amp; ccnumber[1] == 4) || (ccnumber[0] == 5 amp;amp; ccnumber[1] == 5)))
    {
        printf("MASTERCARDn");
    }
    else if ((counter == 13 || counter == 16) amp;amp; (ccnumber[0] == 4))
    {
        printf("VISAn");
    }
    else
    {
        printf("INVALIDn");
        return 0;
    }
}    
else
{
    printf("INVALIDn");
    return 0;
}
 

}