Как перенести слова из одного массива в другой

Вот, данная программа проходится по тексту из 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 шт):

Автор решения: DSuhoi

С помощью функции 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;
}
→ Ссылка
Автор решения: t3f
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).

→ Ссылка
Автор решения: avp

Для начала, идиоматическое чтение файла по строкам пишется вот так:

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()), возможен дополнительный анализ символов в слове и его редактирование и т.д. и т.п.

→ Ссылка