Обновление, привет, ребята, спасибо всем за помощь, мой первоначальный подход был неправильным, и я вообще не использовал коды 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);
}
}
Привет Рашад и добро пожаловать в StackOverflow. Пожалуйста, пройдите тур и прочитайте Как спросить и минимальный воспроизводимый пример и meta.stackoverflow.com/a/285557/7733418
А теперь, когда мы можем увидеть ваш код, подумайте, что произойдет, если входной файл будет содержать менее 2000 символов? Подумайте о том, что возвращает fgetc (и обратите внимание на то, какой тип он возвращает).
Ваш код кажется довольно далеким от подхода, который вы описываете. Пожалуйста, покажите свой код для поиска хотя бы одного слова и простой его печати. Затем попробуйте следующий шаг для сохранения первого найденного слова в подходящей переменной (например, в словаре). Затем укажите, какие из следующих концепций вам известны: массивы, динамическое выделение памяти, связанные списки, хеширование ввода.
спасибо, ребята, я думаю, вы правы, сравнение напрямую с пробелом намного лучше, чем преобразование всего в код ASCII. Первоначально я изучал Python раньше, и в Python я могу создать пустой список или пустой словарь и продолжать добавлять к нему, но я не могу сделать то же самое на языке C, однако это задание для моего университетского класса и текст, который я m должен читать очень короткий, на самом деле профессор использовал тот же метод в примере (она предположила, что предложение содержит только 300 символов при использовании цикла for, и посчитала их. Я исправлю и напишу комментарии к своей программе
for(int i=0;i<2000;i+=1)
-> while ((ch=fgetc(test)) != EOF)
И то, что вы намереваетесь «повторить процесы и подсчитать, сколько повторений у нас есть для каждого слова» [sic] без предоставления какой-либо структуры данных для хранения предыдущих увиденных слов и количество просмотров каждого слова равно не понятно.
В 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
.
Если мы говорим о простом 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;
}
Усилия похвальны, но я подозреваю, что они могут немного выходить за рамки реальной проблемы, хотя ваше простое прочтение вопроса, требующее «слов», является точным. Почему-то я подозреваю, что им нужно количество символов.
@DavidC.Rankin oooops, перечитывая, вы правы, фейспалм :)))))
Посмеиваясь, я могу представить, как глаза бедного спрашивающего закатились, когда realloc()
было достигнуто :)
Тот факт, что ASCII определяет коды до 127, не означает, что fgetc
будет возвращать значения только до 127, поэтому использование int dictionary[128] = {0};
может привести к переполнению. int dictionary[UCHAR_MAX+1] = {0};
безопаснее (и включите <limits.h>
).
@EricPostpischil обратите внимание, что я фильтрую с помощью if ((c > 0) && (c < 128))
, теоретически переполнения быть не может.
Вы никогда не должны использовать магические числа . Если вы хотите сравнить символ с пробелом (в частности), сравните его с пробелом
' '
. Если вы хотите проверить наличие какого-либо символа пробела (включая новую строку или табуляцию), используйте одну из стандартных функций классификации символов, например,isspace
.