Как получить код ASCII для символов из текстового файла?

Обновление, привет, ребята, спасибо всем за помощь, мой первоначальный подход был неправильным, и я вообще не использовал коды ASCII. Извините за поздний повтор, у меня сегодня был выходной на полдня, и я сделал новый пост для полного кода. ошибок нет, но программа работает некорректно ( это обновление старого поста ) Я написал программу, и она работает без ошибок, но она не дает мне желаемых результатов.

Моя единственная проблема, когда я читаю символ, как проверить его ASCII и сохранить его.

#include <stdio.h>
#include <string.h>
int main()
{
 char dictionary[300];
 char ch, temp1, temp2;
 FILE *test;
 test=fopen("HW2.txt","r");
 for(int i=0;i<2000;i+=1)
  { ch=fgetc(test);
    printf("%c",ch);
  }
}

Вы никогда не должны использовать магические числа . Если вы хотите сравнить символ с пробелом (в частности), сравните его с пробелом ' '. Если вы хотите проверить наличие какого-либо символа пробела (включая новую строку или табуляцию), используйте одну из стандартных функций классификации символов, например, isspace.

Some programmer dude 26.12.2020 09:53

Привет Рашад и добро пожаловать в StackOverflow. Пожалуйста, пройдите тур и прочитайте Как спросить и минимальный воспроизводимый пример и meta.stackoverflow.com/a/285557/7733418

Yunnosch 26.12.2020 09:53

А теперь, когда мы можем увидеть ваш код, подумайте, что произойдет, если входной файл будет содержать менее 2000 символов? Подумайте о том, что возвращает fgetc (и обратите внимание на то, какой тип он возвращает).

Some programmer dude 26.12.2020 09:57

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

Yunnosch 26.12.2020 09:59

спасибо, ребята, я думаю, вы правы, сравнение напрямую с пробелом намного лучше, чем преобразование всего в код ASCII. Первоначально я изучал Python раньше, и в Python я могу создать пустой список или пустой словарь и продолжать добавлять к нему, но я не могу сделать то же самое на языке C, однако это задание для моего университетского класса и текст, который я m должен читать очень короткий, на самом деле профессор использовал тот же метод в примере (она предположила, что предложение содержит только 300 символов при использовании цикла for, и посчитала их. Я исправлю и напишу комментарии к своей программе

Rashad 26.12.2020 10:10
for(int i=0;i<2000;i+=1) -> while ((ch=fgetc(test)) != EOF) И то, что вы намереваетесь «повторить процесы и подсчитать, сколько повторений у нас есть для каждого слова» [sic] без предоставления какой-либо структуры данных для хранения предыдущих увиденных слов и количество просмотров каждого слова равно не понятно.
David C. Rankin 26.12.2020 11:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
1 321
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В C символы — это, по сути, их ASCII-код (точнее, их char или unsigned char значение). Итак, когда вы читаете символ, у вас уже есть его код ASCII.

Однако fgetc() не всегда возвращает прочитанный для вас символ; он может потерпеть неудачу, по этой причине он возвращает int, а не unsigned char, который будет -1 в случае сбоя.

Так:

  • Вам нужно определить переменную int, чтобы получить результат fgetc().
  • Если это не EOF, вы можете преобразовать результат обратно в unsigned char. Это ваш символ и одновременно значение ASCII.

PS - I'm ignoring non-ASCII characters, non-Latin languages etc. (But C mostly ignores them in its basic standard library functions too.)

К вашему сведению, fgetc возвращает либо EOF, либо значение unsigned char, преобразованное в значение int, а не значение char.

Eric Postpischil 26.12.2020 14:17
Ответ принят как подходящий

Если мы говорим о простом ASCII, значения идут от 0 до 127, ваша таблица должна выглядеть так:

int dictionary[128] = {0};

Что касается вашего вопроса:

как проверить его ASCII и сохранить его

Считайте, что char — это крошечный int, они взаимозаменяемы, и вам не нужно преобразование.

fgetc требуется int для обработки EOF, и попытка прочитать 2000 символов из файла, содержащего менее 2000 байт, может иметь очень плохие последствия, чтобы прочитать весь файл:

int c;

while ((c = fgetc(test)) != EOF)
{
    if ((c > 0) && (c < 128))
    {
        dictionary[c]++;
    }
}
for (int i = 1; i < 128; i++)
{
    if (dictionary[i] > 0)
    {
        printf("%c appeared %d times\n", i, dictionary[i]);
    }
}

Обновлено:

Перечитывая, я вижу, что вы хотите хранить слова, а не символы, ок, тогда немного сложнее, но ничего страшного, не ограничивайте себя 300 словами, используйте динамическую память:

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

// A struct to hold the words and the
// number of times it appears
struct words
{
    size_t count;
    char *word;
};

int main(void)
{
    FILE *file;

    file = fopen("HW2.txt", "r");
    // Always check the result of fopen 
    if (file == NULL)
    {
        perror("fopen");
        exit(EXIT_FAILURE);
    }
    
    struct words *words = NULL;
    size_t nwords = 0;
    char *word = NULL;
    size_t nchars = 1;
    size_t i;
    int c;

    // while there is text to scan
    while ((c = fgetc(file)) != EOF)
    {
        if (isspace(c))
        {
            if (word != NULL)
            {
                // Search the word in the table
                for (i = 0; i < nwords; i++)
                {
                    // Found, increment the counter
                    if (strcmp(word, words[i].word) == 0)
                    {
                        words[i].count++;
                        free(word);
                        break;
                    }
                }
                // Not found, add the word to the table
                if (i == nwords)
                {
                    struct words *temp;

                    temp = realloc(words, sizeof(*temp) * (nwords + 1));
                    if (temp == NULL)
                    {
                        perror("realloc");
                        exit(EXIT_FAILURE);
                    }
                    words = temp;
                    words[nwords].word = word;
                    words[nwords].count = 1;
                    nwords++;
                }
                // Prepare the next word
                word = NULL;
                nchars = 1;
            }
        }
        else
        {
            char *temp;

            temp = realloc(word, nchars + 1);
            if (temp == NULL)
            {
                perror("realloc");
                exit(EXIT_FAILURE);
            }
            word = temp;
            word[nchars - 1] = (char)c;
            word[nchars++] = '\0';
        }
    }
    for (i = 0; i < nwords; i++)
    {
        printf("%s appeared %zu times\n", words[i].word, words[i].count);
        free(words[i].word);
    }
    free(words);
    fclose(file);
    return 0;
}

Усилия похвальны, но я подозреваю, что они могут немного выходить за рамки реальной проблемы, хотя ваше простое прочтение вопроса, требующее «слов», является точным. Почему-то я подозреваю, что им нужно количество символов.

David C. Rankin 26.12.2020 11:57

@DavidC.Rankin oooops, перечитывая, вы правы, фейспалм :)))))

David Ranieri 26.12.2020 12:00

Посмеиваясь, я могу представить, как глаза бедного спрашивающего закатились, когда realloc() было достигнуто :)

David C. Rankin 26.12.2020 12:09

Тот факт, что ASCII определяет коды до 127, не означает, что fgetc будет возвращать значения только до 127, поэтому использование int dictionary[128] = {0}; может привести к переполнению. int dictionary[UCHAR_MAX+1] = {0}; безопаснее (и включите <limits.h>).

Eric Postpischil 26.12.2020 14:19

@EricPostpischil обратите внимание, что я фильтрую с помощью if ((c > 0) && (c < 128)), теоретически переполнения быть не может.

David Ranieri 26.12.2020 15:09

Другие вопросы по теме