Имеют ли char в C предварительно назначенные нулевые индексированные значения?

Извините, если мой заголовок немного вводит в заблуждение, я все еще новичок во многих из них, но:

Недавно я работал над небольшим проектом шифрования, в котором пользователь может указать файлу аргумент в командной строке, но он должен быть в алфавитном порядке. (Пример: ./file abc)

Затем этот аргумент будет использован в формуле для шифрования предоставленного вами сообщения в виде простого текста. Я получил код для работы, спасибо моему другу за помощь, но я не на 100% конкретная часть этой формулы.

    #include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>


int main (int argc, string argv[])
{   //Clarify that the argument count is not larger than 2
    if (argc != 2)
    {
        printf("Please Submit a Valid Argument.\n");
        return 1;
    }
    //Store the given arguemnt (our key) inside a string var 'k' and check if it is alpha
    string k = (argv[1]);
    //Store how long the key is
    int kLen = strlen(k);
    //Tell the user we are checking their key
    printf("Checking key validation...\n");
    //Pause the program for 2 seconds
    sleep(2);
    //Check to make sure the key submitted is alphabetical
    for (int h = 0, strlk = strlen(k); h < strlk; h++)
    {
        if isalpha(k[h])
        {
            printf("Character %c is valid\n", k[h]);
            sleep(1);
        }
        else
        {   //Telling the user the key is invalid and returning them to the console
            printf("Key is not alphabetical, please try again!\n");
            return 0;
        }

    }
    //Store the users soon to be enciphered text in a string var 'pt'
    string pt = get_string("Please enter the text to be enciphered: ");
    //A prompt that the encrypted text will display on
    printf("Printing encrypted text: ");
    sleep(2);
    //Encipher Function
    for(int i = 0, j = 0, strl = strlen(pt); i < strl; i++)
    {
        //Get the letter 'key'
        int lk = tolower(k[j % kLen]) - 'a';
        //If the char is uppercase, run the V formula and increment j by 1
        if isupper(pt[i])
        {
            printf("%c", 'A' + (pt[i] - 'A' + lk) % 26);
            j++;
        }
        //If the char is lowercase, run the V formula and increment j by 1
        else if islower(pt[i])
        {
            printf("%c", 'a' + (pt[i] - 'a' + lk) % 26);
            j++;
        }
        //If the char is a symbol just print said symbol
        else
        {
            printf("%c", pt[i]);
        }
    }
    printf("\n");
    printf("Closing Script...\n");
    return 0;
}

Функция шифрования: использует «A» в качестве символа для заполнителя, но автоматически ли «A» содержит нулевое индексированное значение? (B = 1, C = 2, ...)


person Josh Gohr    schedule 19.02.2019    source источник


Ответы (4)


В C символьные литералы, такие как 'A', относятся к типу int и представляют любое целочисленное значение, кодирующее символ A в вашей системе. В 99,999 ...% систем, использующих кодировку символов ASCII, это число 65. Если у вас есть старый мэйнфрейм IBM 1970-х годов, использующий EBCDIC, это может быть что-то другое. Вы заметите, что код вычитает 'A', чтобы получить значения, отсчитываемые от нуля.

Это делает предположение, что буквы A-Z занимают 26 последовательных кодов. Это верно для ASCII (A = 65, B = 66 и т. Д.), Но не для всех кодов и не гарантируется языком.

person Lee Daniel Crocker    schedule 20.02.2019

'A' автоматически сохраняет нулевое индексированное значение? (B = 1, C = 2, ...)

Нет. Строго соответствующий код C не может зависеть от какой-либо кодировки символов, кроме последовательного представления цифр _1 _-_ 2_, даже если общий набор символов ASCII представляет их последовательно.

Единственная гарантия в отношении наборов символов - на 5.2.1 Символ устанавливает, параграф 3 стандарта C:

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

Наборы символов, такие как EBCDIC, не представляют буквы последовательно.

person Andrew Henle    schedule 20.02.2019

char - числовой тип, который также часто используется для представления видимых символов (или специальных невидимых псевдосимволов). 'A' - это значение (с фактическим типом int), которое может быть преобразовано в char без переполнения или потери значимости. То есть на самом деле это какое-то число, но обычно вам не нужно знать, какое число, поскольку вы обычно используете конкретное значение char либо просто как число, либо как просто символ, а не то и другое вместе.

Но эта программа использует значения char обоими способами, поэтому отчасти имеет значение, какие числовые значения соответствуют видимым символам. Один из способов, которым это делается очень часто, но не всегда, - это использование ASCII значения, пронумерованные от 0 до 127, или какая-либо другая схема, в которой используются эти значения и другие значения за пределами этого диапазона. Так, например, если компьютер использует одну из этих схем, тогда 'A'==65 и 'A'+1==66, то есть 'B'.

Эта программа предполагает, что все строчные буквы латинского алфавита имеют числовые значения в последовательном порядке от 'a' до 'z', а все прописные буквы латинского алфавита имеют числовые значения в последовательном порядке от 'A' до 'Z', не заботясь о том, какие именно эти значения. Это верно для ASCII, поэтому он будет работать на многих типах машин. Но нет никакой гарантии, что это всегда будет правдой!

C гарантирует, что десятизначные символы от '0' до '9' расположены в последовательном порядке, что означает, что если n является числом от нуля до девяти включительно, то n + '0' является символом для отображения этой цифры, и если c является таким цифровым символом, тогда c - '0' - это число от нуля до девяти, которое оно представляет. Но это единственная гарантия, которую дает язык C относительно значений символов.

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

person aschepler    schedule 20.02.2019

Последовательность - это только один аспект, вызывающий беспокойство.

Правильное использование isalpha(ch) - еще один, не совсем должным образом реализованный в коде OP.

isalpha(ch) ожидает ch в диапазоне unsigned char или EOF. С k[h], char это значение может быть отрицательным. Застрахуйте неотрицательную стоимость с помощью:

// if  isalpha(k[h])
if isalpha((unsigned char) k[h])
person chux - Reinstate Monica    schedule 20.02.2019
comment
@Broman OP вызывает озабоченность по поводу нишевой проблемы, последовательности A-Z, чего-то, что не имеет значения, учитывая символы кодировки 2019 года, но при этом отсутствует более вероятная проблема отказа (UB) функций is...(). - person chux - Reinstate Monica; 20.02.2019