Что не так в моем коде C для программы о strcmp()?

Я пишу программу для сравнения двух строк без использования strcmp(). Но я не могу получить желаемый результат. Вот код моей программы.

#include<stdio.h>
int main(int argc, char const *argv[]) {
   int i,j;
   char a[90],b[90];
   printf("Enter the first string:");
   scanf("%s", &a[90]);
   printf("Enter the second string:");
   scanf("%s", &b[90]);
   for ( i = 0; a[i] != '\0' && b[i] != '\0'; i++) {
      if (a[i] == b[i]) {
         /* code */
         printf("Equal %d \n", a[i]-b[i]);
continue;
      } if (a[i] > b[i]) {
         /* code */
         printf("ai is big %d \n", a[i]-b[i]);
         break;
      }
      if (a[i] < b[i]) {
         /* code */
         printf("%d bi is the biggest \n", a[i]-b[i]);
         break;
      }

   }


   return 0;
}

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


person sharik sid    schedule 12.12.2016    source источник
comment
Чего вы пытаетесь достичь, передавая элемент после последнего в scanf? Кроме неопределенного поведения...   -  person Eugene Sh.    schedule 12.12.2016
comment
Ваш буфер составляет 90 единиц. Но вы используете нулевой индекс для доступа к частям в буфере. Таким образом, вы должны использовать от 0 до 89. Не от 1 до 90.   -  person Andrew Truckle    schedule 12.12.2016
comment
Не используйте тег C++ для вопросов о C.   -  person Lightness Races in Orbit    schedule 12.12.2016
comment
Не берите адрес последнего элемента вашего массива символов. Для строк C (пустых) требуется как минимум 1 элемент для хранения нулевого терминатора.   -  person Andon M. Coleman    schedule 12.12.2016


Ответы (3)


Имя вашего первого массива a, а не a[90].

Точно так же имя вашего второго массива — b, а не b[90].

Выражения a[90] и b[90] называют один элемент после окончания a и b.

Итак, написав &a[90] и &b[90], вы указываете scanf писать сразу после каждого массива, что очень плохо и неправильно.

Вы наверное имели ввиду &a[0] и &b[0]?

Однако scanf очень опасен, и вам вообще не следует его использовать.

person Lightness Races in Orbit    schedule 12.12.2016
comment
Thnxxx я получил ошибку - person sharik sid; 26.12.2016

Выражения '&a[90]' и '&b[90]' генерируют адреса последних записей в массивах a и b. Это означает, что вы читаете строки в нераспределенную память стека, а не в массивы. Вам нужно просто использовать простые «a» и «b» в вызовах scanf().

Если вы сейчас задаетесь вопросом: «Откуда scanf знает, что нужно ограничить длину строки 90 символами?», ответ будет: ЭТО НИКОГДА НЕ ДЕЛАЕТ. Scanf предполагает, что вызывающая сторона предоставила достаточно места в буфере для введенной строки (включая завершающий нуль-символ). Если вам действительно нужно иметь возможность вводить произвольно длинные строки, вам придется выполнять гораздо более сложное управление буфером. Если вы хотите убедиться, что когда-либо вводилось менее 90 символов, вам нужно перейти к получению одного символа за раз (и я считаю, что вам придется явно проверять завершающую новую строку) и подсчитать их, чтобы убедиться, что вы не переполнить буфер.

person PMar    schedule 12.12.2016
comment
&a[90] на самом деле оценивается как указатель сразу за концом массива a, а не на его последний элемент. Аналогично &b[90]. Что касается того, как scanf() может знать об ограничении размера строк, это может быть передано ему через компоненты ширины в дескрипторах полей в строке формата (например, %89s). Однако вы правы, что если вы не укажете ширину, то scanf() ничего не знает; это важный момент. - person John Bollinger; 12.12.2016
comment
Каждое из выражений '&a[90]' и '&b[90]' генерирует адреса последних записей в массивах a и b. Нет, не - person Lightness Races in Orbit; 12.12.2016
comment
Более безопасные альтернативы scanf("%s") включают scanf("%89s") (хотя вы захотите проверить, возможно, с помощью %n, не закончилось ли у вас место), fgets() (но не gets()) и (в системах POSIX.1-2008) scanf("%ms"). - person Toby Speight; 12.12.2016

Существует некоторая проблема с данным рассматриваемым кодом.

вопросы

1- Неиспользуемая переменная j.

2- При получении строки от пользователя в scanf используются a[90] и b[90], что означает, что строка будет храниться с 90-го индекса массива. Это может привести к некоторым проблемам с памятью, и выходные данные будут иметь некоторые значения мусора.

Хорошо использовать a[0] и b[0] в scanf. Мы можем использовать имя массива в scanf, так как имя массива указывает на начальный адрес массива.

scanf ("%s", a); 

scanf ("%s", b);

Правильный код:

#include "stdio.h"

int main(int argc, char const *argv[]) 
{

        int i;
        char a[90],b[90];
        printf("Enter the first string:");
        scanf("%s", a);
        printf("Enter the second string:");
        scanf("%s", b);
        for ( i = 0; a[i] != '\0' || b[i] != '\0'; i++) {
                if (a[i] == b[i]) {
                        /* code */
                        printf("Equal %d \n", a[i]-b[i]);
                        continue;
                } if (a[i] > b[i]) {
                        /* code */
                        printf("a is big %d \n", a[i]-b[i]);
                        break;
                }
                if (a[i] < b[i]) {
                        /* code */
                        printf("%d b is the biggest \n", a[i]-b[i]);
                        break;
                }

        }
        return 0;
}
person Anubhav Gupta    schedule 12.12.2016
comment
a[90] приведет к мусорным значениям, если вам повезет. Это неопределенное поведение. Кроме того, a затухает по адресу первого элемента a, а не по адресу a. &a[0] является указателем на char, а a затухает до этого значения. &a — это указатель на массив chars с типом (char *)[90]. Возможно, это то, что вы имели в виду, но это могло бы быть более ясно. - person ad absurdum; 12.12.2016