Как перенести слова из одного массива в другой
Вот, данная программа проходится по тексту из test.txt, записывает все слова в переменную istr. Хочу чтобы из переменной в istr слова передавались в strok[words], и чтобы каждое слово было под своим адресом.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 100
int main(void) {
int words=0;
char str[LEN];
char* istr;
char** strok=calloc(100,1);
//char *istr1;
FILE* fp = fopen("test.txt", "r");;
printf("\nТекст файла\n\n");
for (int i = 0; i < 10; i++) {
istr = fgets(str, LEN, fp);
//printf("%s", istr);
for ( istr = strtok(str, " .\t\n"); istr; istr = strtok(NULL, " .\t\n")) {
char* st=malloc(20);
strok[words]=calloc(20,1);
sscanf(istr, "%s", strok[words]);
sprintf(istr, "%s", strok[words]);//пытался и в sscanf и тут, не выходит
words++;
printf("%p\n", &strok[words]);
printf("%s\n", strok[words]);
}
}
fclose(fp);
return 0;
}
Ответы (3 шт):
С помощью функции fscanf() проще считывать данные с файлов:
#include <stdio.h>
#include <stdlib.h>
#define LEN 100 //количество строк
#define LEN_STR 32 //количество символов в строке
int isMarks(char ch){
return (ch=='.' || ch==',' || ch==';' || ch=='?' || ch=='!') ? 1 : 0;
}
int main(void) {
int words = 0; //кол-во слов на запись
char strok[LEN][LEN_STR];
FILE* fp = fopen("text.txt", "r");
//проверка файла
if(fp==NULL){ printf("Error!\n"); return 0; }
printf("\nТекст файла\n\n");
while (!feof(fp))
fscanf(fp,"%s", strok[words++]); //чтение в массив
fclose(fp);
//удаление знаков синтаксиса
for(int i=0; i<words; i++)
for(int j=0; j<LEN_STR; j++)
if(isMarks(strok[i][j])){
strok[i][j] = '\0';
}
//вывод результата
for(int i=0; i<words-1; i++)
printf("%d. %s\n",(i+1), strok[i]);
return 0;
}
char **words = NULL; //указатель на массив слов
int count = 0; //количество слов
FILE *file = fopen("test.txt", "r");
fseek(file, 0, SEEK_END); //определяем размер файла и выделяем буфер нужного размера
int size = ftell(file);
char *buffer = malloc(size + 1);
rewind(file); //считываем текст и добавляем завершающий \0 в конце
buffer[fread(buffer, 1, size, file)] = '\0'; //* (смотри примечание ниже)
fclose(file);
char *delimiters = " .,!'';?:-()+-*%@&<>/\\\"\n\t"; //символы-разделители
char *pword = strtok(buffer, delimiters);
while (pword) {
words = realloc(words, (count + 1) * sizeof(char*)); //добавляем новый элемент в массив
words[count++] = pword; //записываем в него указатель на слово и увеличиваем счётчик
pword = strtok(NULL, delimiters);
}
//вывод:
int i;
printf("файл содержит %d слов:\n", count);
for (i = 0; i < count; i++) puts(words[i]);
*: когда файл открыт в текстовом режиме fread может выполнять некоторые преобразования (например заменять \r\n на \n), поэтому определяя позицию завершающего \0 следует ориентироваться не на размер файла, а на количество записанных в буфер символов (которое возвращает fread).
Для начала, идиоматическое чтение файла по строкам пишется вот так:
while (fgets(str, LEN, fp)) {
...
}
Теперь, в цикле for с вызовом strtok() вы получаете искомые слова, завершающиеся нулем (из каких символов они состоят, зависит от набора разделителей, который вы передаете в strtok()). Внутри цикла у вас на очередное слово указывает переменная istr.
Для достижения желаемой цели вам остается скопировать очередное слово в новый элемент массива.
Для этого надо убедиться, что текущий размер массива достаточен (если нет, расширим массив). Допустим, в начале вы добавите переменную, содержащую размер массива
size_t s_size = 10;
а затем создадите массив (как вы это и делаете)
char **strok = malloc(s_size * sizeof(char *));
Тогда перемещение очередного слова (точнее его копии в динамической памяти) в массив можно сделать так
if (words == s_size) {
s_size *= 2;
strok = realloc(strok, s_size * sizeof(char *));
}
strok[words++] = strdup(istr);
Вот, собственно, и вся программа.
(между прочим, вы и сами практически ее написали, только немного запутались в ... -))
Конечно, после realloc надо бы проверить, что память реально выделена и аккуратно завершиться, если памяти больше нет. После while (fgets(...)) можно проверить, не завершилось ли чтение строки с ошибкой (функция ferror()), возможен дополнительный анализ символов в слове и его редактирование и т.д. и т.п.