Я пытаюсь извлечь слова из файла .txt, который содержит следующее предложение
Quando avevo cinqve anni, mia made mi perpeteva sempre che la felicita e la chiave della vita. Quando andai a squola mi domandrono come vuolessi essere da grande. Io scrissi: selice. Mi dissero che non avevo capito il corpito, e io dissi loro che non avevano capito la wita.
Проблема в том, что в массиве, который я использую для хранения слов, он также хранит пустые слова ' ', которые всегда идут после одного из следующих ',''.'':'
Я знаю, что такие вещи, как «пустые слова» или «пустые символы» не имеют смысла, но попробуйте код с текстом, который я передал, и вы все поймете.
Тем временем я пытаюсь понять использование sscanf с этим модификатором sscanf(buffer, "%[^.,:]");, который должен позволить мне хранить строки, игнорируя символы ., , и :, однако я не знаю, что i должен писать в %[^], чтобы игнорировать пустой символ ' ', который всегда спасается.
Код следующий
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static void load_array(const char* file_name){
char buffer[2048];
char a[100][100];
int buf_size = 2048;
FILE *fp;
int j = 0, c = 0;
printf("\nLoading data from file...\n");
fp = fopen(file_name,"r");
if (fp == NULL){
fprintf(stderr,"main: unable to open the file");
exit(EXIT_FAILURE);
}
fgets(buffer,buf_size,fp);
//here i store each word in an array of strings when I encounter
//an unwanted char I save the word into the next element of the
//array
for(int i = 0; i < strlen(buffer); i++) {
if ((buffer[i] >= 'a' && buffer[i] <= 'z') || (buffer[i] >= 'A' && buffer[i] <= 'Z')) {
a[j][c++] = buffer[i];
} else {
j++;
c = 0;
continue;
}
}
//this print is used only to see the words in the array of strings
for(int i = 0; i < 100; i++)
printf("%s %d\n", a[i], i);
fclose(fp);
printf("\nData loaded\n");
}
//Here I pass the file_name from command line
int main(int argc, char const *argv[]) {
if (argc < 2) {
printf("Usage: ordered_array_main <file_name>\n");
exit(EXIT_FAILURE);
}
load_array(argv[1]);
}
Я знаю, что я должен хранить только необходимое число и слова, а не 100 каждый раз, я хочу подумать об этом позже, прямо сейчас я хочу исправить проблему с пустыми словами.
Составление и исполнение
gcc -o testloadfile testloadfile.c
./testloadfile "correctme.txt"
И здесь может помочь использование отладчика.





вместо этого вы можете попробовать использовать strtok
fgets(buffer,buf_size,fp);
for (char* tok = strtok(buffer,".,: "); *tok; tok = strtok(NULL,".,: "))
{
printf("%s\n", tok);
}
Примечание: если вы хотите сохранить то, что возвращает strtok, вам нужно либо скопировать содержимое того, на что указывает tok, либо выделить копию с помощью strdup / malloc + strcpy, поскольку strtok изменяет свою копию первого аргумента при анализе строки.
Нет, strtok не пропускает автоматически пустое пространство (с каких это пор?). Более того, ваш код ложный (отсутствует ')' в конце цикла for).
@ Tom's, как я могу пропустить пустое место, если strtok этого не делает?
Добавив '' в разделитель strtok.
Вы забыли добавить последний '\0' в каждую строку a, и ваш алгоритм имеет много недостатков (например, как вы увеличиваете j каждый раз, когда появляется не-буква. Что, если у вас есть ", "? Вы увеличиваете два раза вместо одного).
Один из «простых» способов - использовать strtok, как показывает вам Андерс К..
fgets(buffer,buf_size,fp);
for (char* tok = strtok(buffer,".,:"); *tok; tok = strtok(NULL,".,:")) {
printf("%s\n", tok);
}
«Проблема» этой функции в том, что вам нужно указать весь разделитель, поэтому вам нужно добавить ' ' (пробел), '\t' (табуляция) и т. д.
Поскольку вам нужно только "слово", как описано как "содержать только букву, минускул или маюскуле", вы можете сделать следующее:
int main(void)
{
char line[] = "Hello ! What a beautiful day, isn't it ?";
char *beginWord = NULL;
for (size_t i = 0; line[i]; ++i) {
if (isalpha(line[i])) { // upper or lower letter ==> valid character for a word
if (!beginWord) {
// We found the beginning of a word
beginWord = line + i;
}
} else {
if (beginWord) {
// We found the end of a word
char tmp = line[i];
line[i] = '\0';
printf("'%s'\n", beginWord);
line[i] = tmp;
beginWord = NULL;
}
}
}
return (0);
}
Обратите внимание, как «not» делится на «isn» и «t», поскольку ' не является подходящим символом для вашего слова.
Алгоритм довольно прост: мы просто зацикливаем строку, и если это допустимая буква и beginWord == NULL, то это начало слова. Если это неверная буква и beginWord != NULL, то это конец слова. Тогда вы можете иметь любое количество букв между двумя словами, вы все равно можете четко определить слово.
Вы забыли добавить последний '\ 0' в каждую строку
a. И ваш алгоритм имеет много недостатков (например, как вы увеличиваете j каждый раз, когда появляется не буква. Что, если у вас есть ","? Вы увеличиваете два раза вместо одного). Советую посмотреть "стрток"